diff options
author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/include/clang/Driver/Option.h | |
parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/include/clang/Driver/Option.h')
-rw-r--r-- | clang/include/clang/Driver/Option.h | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/clang/include/clang/Driver/Option.h b/clang/include/clang/Driver/Option.h new file mode 100644 index 0000000..8243f6d --- /dev/null +++ b/clang/include/clang/Driver/Option.h @@ -0,0 +1,318 @@ +//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_OPTION_H_ +#define CLANG_DRIVER_OPTION_H_ + +#include "clang/Driver/OptSpecifier.h" +#include "llvm/ADT/StringRef.h" +#include "clang/Basic/LLVM.h" + +namespace clang { +namespace driver { + class Arg; + class ArgList; + class OptionGroup; + + /// Option - Abstract representation for a single form of driver + /// argument. + /// + /// An Option class represents a form of option that the driver + /// takes, for example how many arguments the option has and how + /// they can be provided. Individual option instances store + /// additional information about what group the option is a member + /// of (if any), if the option is an alias, and a number of + /// flags. At runtime the driver parses the command line into + /// concrete Arg instances, each of which corresponds to a + /// particular Option instance. + class Option { + public: + enum OptionClass { + GroupClass = 0, + InputClass, + UnknownClass, + FlagClass, + JoinedClass, + SeparateClass, + CommaJoinedClass, + MultiArgClass, + JoinedOrSeparateClass, + JoinedAndSeparateClass + }; + + enum RenderStyleKind { + RenderCommaJoinedStyle, + RenderJoinedStyle, + RenderSeparateStyle, + 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. + + // 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; + + protected: + Option(OptionClass Kind, OptSpecifier ID, const char *Name, + const OptionGroup *Group, const Option *Alias); + public: + virtual ~Option(); + + 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; } + + bool isUnsupported() const { return Unsupported; } + void setUnsupported(bool Value) { Unsupported = Value; } + + bool isLinkerInput() const { return LinkerInput; } + void setLinkerInput(bool Value) { LinkerInput = Value; } + + bool hasNoOptAsInput() const { return NoOptAsInput; } + void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } + + RenderStyleKind getRenderStyle() const { + return RenderStyleKind(RenderStyle); + } + 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 hasForwardToGCC() const { + return !NoForward && !DriverOption && !LinkerInput; + } + + /// 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; + } + + /// getRenderName - Return the name to use when rendering this + /// option. + StringRef getRenderName() const { + return getUnaliasedOption()->getName(); + } + + /// matches - Predicate for whether this option is part of the + /// given option (which may be a group). + /// + /// Note that matches against options which are an alias should never be + /// done -- aliases do not participate in matching and so such a query will + /// always be false. + bool matches(OptSpecifier ID) const; + + /// accept - Potentially accept the current argument, returning a + /// new Arg instance, or 0 if the option does not accept this + /// argument (or the argument is missing values). + /// + /// 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; + + 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 +} // end namespace clang + +#endif |