diff options
Diffstat (limited to 'include/clang/Driver/Option.h')
-rw-r--r-- | include/clang/Driver/Option.h | 324 |
1 files changed, 102 insertions, 222 deletions
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h index e6c4e12..c3db773 100644 --- a/include/clang/Driver/Option.h +++ b/include/clang/Driver/Option.h @@ -10,15 +10,36 @@ #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 { namespace driver { class Arg; class ArgList; - class OptionGroup; + +namespace options { + /// Base flags for all options. Custom flags may be added after. + enum DriverFlag { + HelpHidden = (1 << 0), + RenderAsInput = (1 << 1), + RenderJoined = (1 << 2), + RenderSeparate = (1 << 3) + }; + + /// Flags specifically for clang options. + enum ClangFlags { + DriverOption = (1 << 4), + LinkerInput = (1 << 5), + NoArgumentUnused = (1 << 6), + NoForward = (1 << 7), + Unsupported = (1 << 8), + CC1Option = (1 << 9), + NoDriverOption = (1 << 10) + }; +} /// Option - Abstract representation for a single form of driver /// argument. @@ -53,100 +74,104 @@ namespace driver { RenderValuesStyle }; - private: - OptionClass Kind; - - /// The option ID. - OptSpecifier ID; - - /// The option name. - StringRef Name; - - /// Group this option is a member of, if any. - const OptionGroup *Group; - - /// Option that this is an alias for, if any. - const Option *Alias; - - /// 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. + protected: + const OptTable::Info *Info; + const OptTable *Owner; - // FIXME: We should ditch the render/renderAsInput distinction. - bool NoOptAsInput : 1; + public: + Option(const OptTable::Info *Info, const OptTable *Owner); + ~Option(); - /// The style to using when rendering arguments parsed by this option. - unsigned RenderStyle : 2; + bool isValid() const { + return Info != 0; + } - /// This option is only consumed by the driver. - bool DriverOption : 1; + unsigned getID() const { + assert(Info && "Must have a valid info!"); + return Info->ID; + } - /// This option should not report argument unused errors. - bool NoArgumentUnused : 1; + OptionClass getKind() const { + assert(Info && "Must have a valid info!"); + return OptionClass(Info->Kind); + } - /// This option should not be implicitly forwarded. - bool NoForward : 1; + /// \brief Get the name of this option without any prefix. + StringRef getName() const { + assert(Info && "Must have a valid info!"); + return Info->Name; + } - /// CC1Option - This option should be accepted by clang -cc1. - bool CC1Option : 1; + const Option getGroup() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->GroupID); + } - protected: - Option(OptionClass Kind, OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - public: - virtual ~Option(); + const Option getAlias() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->AliasID); + } - unsigned getID() const { return ID.getID(); } - OptionClass getKind() const { return Kind; } - StringRef getName() const { return Name; } - const OptionGroup *getGroup() const { return Group; } - const Option *getAlias() const { return Alias; } + /// \brief Get the default prefix for this option. + StringRef getPrefix() const { + const char *Prefix = *Info->Prefixes; + return Prefix ? Prefix : StringRef(); + } - bool isUnsupported() const { return Unsupported; } - void setUnsupported(bool Value) { Unsupported = Value; } + /// \brief Get the name of this option with the default prefix. + std::string getPrefixedName() const { + std::string Ret = getPrefix(); + Ret += getName(); + return Ret; + } - bool isLinkerInput() const { return LinkerInput; } - void setLinkerInput(bool Value) { LinkerInput = Value; } + unsigned getNumArgs() const { return Info->Param; } - bool hasNoOptAsInput() const { return NoOptAsInput; } - void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } + 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 hasNoArgumentUnused() const { return NoArgumentUnused; } - void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; } - - bool hasNoForward() const { return NoForward; } - void setNoForward(bool Value) { NoForward = Value; } - - bool isCC1Option() const { return CC1Option; } - void setIsCC1Option(bool Value) { CC1Option = Value; } - - bool hasForwardToGCC() const { - return !NoForward && !DriverOption && !LinkerInput; + /// Test if this option has the flag \a Val. + bool hasFlag(unsigned Val) const { + return Info->Flags & Val; } /// getUnaliasedOption - Return the final option this option /// aliases (itself, if the option has no alias). - const Option *getUnaliasedOption() const { - if (Alias) return Alias->getUnaliasedOption(); - return this; + const Option getUnaliasedOption() const { + const Option Alias = getAlias(); + if (Alias.isValid()) return Alias.getUnaliasedOption(); + return *this; } /// getRenderName - Return the name to use when rendering this /// option. StringRef getRenderName() const { - return getUnaliasedOption()->getName(); + return getUnaliasedOption().getName(); } /// matches - Predicate for whether this option is part of the @@ -164,158 +189,13 @@ namespace driver { /// If the option accepts the current argument, accept() sets /// Index to the position where argument parsing should resume /// (even if the argument is missing values). - virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0; + /// + /// \parm ArgSize The number of bytes taken up by the matched Option prefix + /// and name. This is used to determine where joined values + /// start. + Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; void dump() const; - - static bool classof(const Option *) { return true; } - }; - - /// OptionGroup - A set of options which are can be handled uniformly - /// by the driver. - class OptionGroup : public Option { - public: - OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::GroupClass; - } - static bool classof(const OptionGroup *) { return true; } - }; - - // Dummy option classes. - - /// InputOption - Dummy option class for representing driver inputs. - class InputOption : public Option { - public: - InputOption(OptSpecifier ID); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::InputClass; - } - static bool classof(const InputOption *) { return true; } - }; - - /// UnknownOption - Dummy option class for represent unknown arguments. - class UnknownOption : public Option { - public: - UnknownOption(OptSpecifier ID); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::UnknownClass; - } - static bool classof(const UnknownOption *) { return true; } - }; - - // Normal options. - - class FlagOption : public Option { - public: - FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::FlagClass; - } - static bool classof(const FlagOption *) { return true; } - }; - - class JoinedOption : public Option { - public: - JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedClass; - } - static bool classof(const JoinedOption *) { return true; } - }; - - class SeparateOption : public Option { - public: - SeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::SeparateClass; - } - static bool classof(const SeparateOption *) { return true; } - }; - - class CommaJoinedOption : public Option { - public: - CommaJoinedOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::CommaJoinedClass; - } - static bool classof(const CommaJoinedOption *) { return true; } - }; - - // FIXME: Fold MultiArgOption into SeparateOption? - - /// MultiArgOption - An option which takes multiple arguments (these - /// are always separate arguments). - class MultiArgOption : public Option { - unsigned NumArgs; - - public: - MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias, unsigned NumArgs); - - unsigned getNumArgs() const { return NumArgs; } - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::MultiArgClass; - } - static bool classof(const MultiArgOption *) { return true; } - }; - - /// JoinedOrSeparateOption - An option which either literally - /// prefixes its (non-empty) value, or is follwed by a value. - class JoinedOrSeparateOption : public Option { - public: - JoinedOrSeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedOrSeparateClass; - } - static bool classof(const JoinedOrSeparateOption *) { return true; } - }; - - /// JoinedAndSeparateOption - An option which literally prefixes its - /// value and is followed by another value. - class JoinedAndSeparateOption : public Option { - public: - JoinedAndSeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedAndSeparateClass; - } - static bool classof(const JoinedAndSeparateOption *) { return true; } }; } // end namespace driver |