diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h index 27bd11985a..15a22fed20 100644 --- a/include/clang/Driver/OptTable.h +++ b/include/clang/Driver/OptTable.h @@ -15,21 +15,6 @@ namespace clang { namespace driver { -namespace options { - enum DriverFlag { - DriverOption = (1 << 0), - HelpHidden = (1 << 1), - LinkerInput = (1 << 2), - NoArgumentUnused = (1 << 3), - NoForward = (1 << 4), - RenderAsInput = (1 << 5), - RenderJoined = (1 << 6), - RenderSeparate = (1 << 7), - Unsupported = (1 << 8), - CC1Option = (1 << 9) - }; -} - class Arg; class ArgList; class InputArgList; @@ -123,9 +108,7 @@ namespace options { } /// \brief Should the help for the given option be hidden by default. - bool isOptionHelpHidden(OptSpecifier id) const { - return getInfo(id).Flags & options::HelpHidden; - } + bool isOptionHelpHidden(OptSpecifier id) const; /// \brief Get the help text to use to describe this option. const char *getOptionHelpText(OptSpecifier id) const { diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h index 9d86ba6d47..a149f5b0c4 100644 --- a/include/clang/Driver/Option.h +++ b/include/clang/Driver/Option.h @@ -10,8 +10,9 @@ #ifndef CLANG_DRIVER_OPTION_H_ #define CLANG_DRIVER_OPTION_H_ -#include "clang/Driver/OptSpecifier.h" +#include "clang/Driver/OptTable.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" #include "clang/Basic/LLVM.h" namespace clang { @@ -19,6 +20,21 @@ namespace driver { class Arg; class ArgList; +namespace options { + enum DriverFlag { + DriverOption = (1 << 0), + HelpHidden = (1 << 1), + LinkerInput = (1 << 2), + NoArgumentUnused = (1 << 3), + NoForward = (1 << 4), + RenderAsInput = (1 << 5), + RenderJoined = (1 << 6), + RenderSeparate = (1 << 7), + Unsupported = (1 << 8), + CC1Option = (1 << 9) + }; +} + /// Option - Abstract representation for a single form of driver /// argument. /// @@ -53,87 +69,72 @@ namespace driver { }; private: - OptionClass Kind; + const OptTable::Info *Info; /// The option ID. OptSpecifier ID; - /// The option name. - StringRef Name; - /// Group this option is a member of, if any. const Option *Group; /// Option that this is an alias for, if any. const Option *Alias; - unsigned NumArgs; - - /// Unsupported options will be rejected. - bool Unsupported : 1; - - /// Treat this option like a linker input? - bool LinkerInput : 1; - - /// When rendering as an input, don't render the option. - - // FIXME: We should ditch the render/renderAsInput distinction. - bool NoOptAsInput : 1; - - /// The style to using when rendering arguments parsed by this option. - unsigned RenderStyle : 2; - - /// This option is only consumed by the driver. - bool DriverOption : 1; - - /// This option should not report argument unused errors. - bool NoArgumentUnused : 1; - - /// This option should not be implicitly forwarded. - bool NoForward : 1; - - /// CC1Option - This option should be accepted by clang -cc1. - bool CC1Option : 1; - public: - Option(OptionClass Kind, OptSpecifier ID, const char *Name, - const Option *Group, const Option *Alias, unsigned Args); + Option(const OptTable::Info *Info, OptSpecifier ID, + const Option *Group, const Option *Alias); ~Option(); unsigned getID() const { return ID.getID(); } - OptionClass getKind() const { return Kind; } - StringRef getName() const { return Name; } + OptionClass getKind() const { return OptionClass(Info->Kind); } + StringRef getName() const { return Info->Name; } const Option *getGroup() const { return Group; } const Option *getAlias() const { return Alias; } - bool isUnsupported() const { return Unsupported; } - void setUnsupported(bool Value) { Unsupported = Value; } + unsigned getNumArgs() const { return Info->Param; } - bool isLinkerInput() const { return LinkerInput; } - void setLinkerInput(bool Value) { LinkerInput = Value; } + bool isUnsupported() const { return Info->Flags & options::Unsupported; } - bool hasNoOptAsInput() const { return NoOptAsInput; } - void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } + bool isLinkerInput() const { return Info->Flags & options::LinkerInput; } + + bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;} RenderStyleKind getRenderStyle() const { - return RenderStyleKind(RenderStyle); + if (Info->Flags & options::RenderJoined) + return RenderJoinedStyle; + if (Info->Flags & options::RenderSeparate) + return RenderSeparateStyle; + switch (getKind()) { + case GroupClass: + case InputClass: + case UnknownClass: + return RenderValuesStyle; + case JoinedClass: + case JoinedAndSeparateClass: + return RenderJoinedStyle; + case CommaJoinedClass: + return RenderCommaJoinedStyle; + case FlagClass: + case SeparateClass: + case MultiArgClass: + case JoinedOrSeparateClass: + return RenderSeparateStyle; + } + llvm_unreachable("Unexpected kind!"); } - void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; } - bool isDriverOption() const { return DriverOption; } - void setDriverOption(bool Value) { DriverOption = Value; } + bool isDriverOption() const { return Info->Flags & options::DriverOption; } - bool hasNoArgumentUnused() const { return NoArgumentUnused; } - void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; } + bool hasNoArgumentUnused() const { + return Info->Flags & options::NoArgumentUnused; + } - bool hasNoForward() const { return NoForward; } - void setNoForward(bool Value) { NoForward = Value; } + bool hasNoForward() const { return Info->Flags & options::NoForward; } - bool isCC1Option() const { return CC1Option; } - void setIsCC1Option(bool Value) { CC1Option = Value; } + bool isCC1Option() const { return Info->Flags & options::CC1Option; } bool hasForwardToGCC() const { - return !NoForward && !DriverOption && !LinkerInput; + return !hasNoForward() && !isDriverOption() && !isLinkerInput(); } /// getUnaliasedOption - Return the final option this option diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index f8fe05906b..3ebc6d8725 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -129,38 +129,16 @@ OptTable::~OptTable() { delete[] Options; } +bool OptTable::isOptionHelpHidden(OptSpecifier id) const { + return getInfo(id).Flags & options::HelpHidden; +} + Option *OptTable::CreateOption(unsigned id) const { const Info &info = getInfo(id); const Option *Group = getOption(info.GroupID); const Option *Alias = getOption(info.AliasID); - Option *Opt = new Option(Option::OptionClass(info.Kind), - id, info.Name, Group, Alias, info.Param); - - if (info.Flags & DriverOption) - Opt->setDriverOption(true); - if (info.Flags & LinkerInput) - Opt->setLinkerInput(true); - if (info.Flags & NoArgumentUnused) - Opt->setNoArgumentUnused(true); - if (info.Flags & NoForward) - Opt->setNoForward(true); - if (info.Flags & RenderAsInput) - Opt->setNoOptAsInput(true); - if (info.Flags & RenderJoined) { - assert((info.Kind == Option::JoinedOrSeparateClass || - info.Kind == Option::SeparateClass) && "Invalid option."); - Opt->setRenderStyle(Option::RenderJoinedStyle); - } - if (info.Flags & RenderSeparate) { - assert((info.Kind == Option::JoinedOrSeparateClass || - info.Kind == Option::JoinedClass) && "Invalid option."); - Opt->setRenderStyle(Option::RenderSeparateStyle); - } - if (info.Flags & Unsupported) - Opt->setUnsupported(true); - if (info.Flags & CC1Option) - Opt->setIsCC1Option(true); + Option *Opt = new Option(&info, id, Group, Alias); return Opt; } diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp index 8a9c601549..57eaee2213 100644 --- a/lib/Driver/Option.cpp +++ b/lib/Driver/Option.cpp @@ -17,42 +17,15 @@ #include using namespace clang::driver; -Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name, - const Option *_Group, const Option *_Alias, unsigned Args) - : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias), - NumArgs(Args), Unsupported(false), LinkerInput(false), NoOptAsInput(false), - DriverOption(false), NoArgumentUnused(false), NoForward(false) { +Option::Option(const OptTable::Info *info, OptSpecifier _ID, + const Option *_Group, const Option *_Alias) + : Info(info), ID(_ID.getID()), Group(_Group), Alias(_Alias) { // Multi-level aliases are not supported, and alias options cannot // have groups. This just simplifies option tracking, it is not an // inherent limitation. assert((!Alias || (!Alias->Alias && !Group)) && "Multi-level aliases and aliases with groups are unsupported."); - - // Initialize rendering options based on the class. - switch (Kind) { - case GroupClass: - case InputClass: - case UnknownClass: - RenderStyle = RenderValuesStyle; - break; - - case JoinedClass: - case JoinedAndSeparateClass: - RenderStyle = RenderJoinedStyle; - break; - - case CommaJoinedClass: - RenderStyle = RenderCommaJoinedStyle; - break; - - case FlagClass: - case SeparateClass: - case MultiArgClass: - case JoinedOrSeparateClass: - RenderStyle = RenderSeparateStyle; - break; - } } Option::~Option() { @@ -60,7 +33,7 @@ Option::~Option() { void Option::dump() const { llvm::errs() << "<"; - switch (Kind) { + switch (getKind()) { #define P(N) case N: llvm::errs() << #N; break P(GroupClass); P(InputClass); @@ -75,7 +48,7 @@ void Option::dump() const { #undef P } - llvm::errs() << " Name:\"" << Name << '"'; + llvm::errs() << " Name:\"" << getName() << '"'; if (Group) { llvm::errs() << " Group:"; @@ -87,8 +60,8 @@ void Option::dump() const { Alias->dump(); } - if (Kind == MultiArgClass) - llvm::errs() << " NumArgs:" << NumArgs; + if (getKind() == MultiArgClass) + llvm::errs() << " NumArgs:" << getNumArgs(); llvm::errs() << ">\n"; } @@ -108,7 +81,7 @@ bool Option::matches(OptSpecifier Opt) const { } Arg *Option::accept(const ArgList &Args, unsigned &Index) const { - switch (Kind) { + switch (getKind()) { case FlagClass: if (getName().size() != strlen(Args.getArgString(Index))) return 0; @@ -164,14 +137,14 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const { if (getName().size() != strlen(Args.getArgString(Index))) return 0; - Index += 1 + NumArgs; + Index += 1 + getNumArgs(); if (Index > Args.getNumInputArgStrings()) return 0; - Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs, - Args.getArgString(Index - NumArgs)); - for (unsigned i = 1; i != NumArgs; ++i) - A->getValues().push_back(Args.getArgString(Index - NumArgs + i)); + Arg *A = new Arg(getUnaliasedOption(), Index - 1 - getNumArgs(), + Args.getArgString(Index - getNumArgs())); + for (unsigned i = 1; i != getNumArgs(); ++i) + A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i)); return A; } case JoinedOrSeparateClass: {