From: Daniel Dunbar Date: Tue, 3 Mar 2009 05:55:11 +0000 (+0000) Subject: Sketch Driver Option classes. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1eb4e64eed08837b85a375d6a953503daa844f07;p=clang Sketch Driver Option classes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65933 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h new file mode 100644 index 0000000000..cfda80ef46 --- /dev/null +++ b/include/clang/Driver/Option.h @@ -0,0 +1,180 @@ +//===--- 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_ + +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 { + GroupOption = 0, + InputOption, + UnknownOption, + FlagOption, + JoinedOption, + SeparateOption, + CommaJoinedOption, + MultiArgOption, + JoinedOrSeparateOption, + JoinedAndSeparateOption + }; + + private: + OptionClass Kind; + + /// The option name. + const char *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; + + protected: + Option(OptionClass Kind, const char *Name, + OptionGroup *Group, Option *Alias); + + OptionClass getKind() const { return Kind; } + const char *getName() const { return Name; } + const OptionGroup *getGroup() const { return Group; } + const Option *getAlias() const { return Alias; } + + /// 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. + const char *getRenderName() const { + return getUnaliasedOption()->getName(); + } + + /// matches - Predicate for whether this option is part of the + /// given option (which may be a group). + bool matches(const Option *Opt) const; + + /// accept - Potentially accept the current argument, returning a + /// new Arg instance, or 0 if the option does not accept this + /// argument. + /// + /// May issue a missing argument error. + virtual Arg *accept(ArgList &Args, unsigned Index) const = 0; + }; + + /// OptionGroup - A set of options which are can be handled uniformly + /// by the driver. + class OptionGroup : public Option { + OptionGroup *Group; + + public: + OptionGroup(const char *Name, OptionGroup *Group); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + // Dummy option classes. + + /// InputOption - Dummy option class for representing driver inputs. + class InputOption : public Option { + public: + InputOption(); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + /// UnknownOption - Dummy option class for represent unknown arguments. + class UnknownOption : public Option { + public: + UnknownOption(); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + // Normal options. + + class FlagOption : public Option { + public: + FlagOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + class JoinedOption : public Option { + JoinedOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + class CommaJoinedOption : public Option { + CommaJoinedOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + class SeparateOption : public Option { + SeparateOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + /// MultiArgOption - An option which takes multiple arguments (these + /// are always separate arguments). + class MultiArgOption : public Option { + unsigned NumArgs; + + public: + MultiArgOption(const char *Name, OptionGroup *Group, Option *Alias, + unsigned NumArgs); + + unsigned getNumArgs() const { return NumArgs; } + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + /// JoinedOrSeparateOption - An option which either literally + /// prefixes its (non-empty) value, or is follwed by a value. + class JoinedOrSeparateOption : public Option { + JoinedOrSeparateOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + + /// JoinedAndSeparateOption - An option which literally prefixes its + /// value and is followed by another value. + class JoinedAndSeparateOption : public Option { + JoinedAndSeparateOption(const char *Name, OptionGroup *Group, Option *Alias); + + virtual Arg *accept(ArgList &Args, unsigned Index) const; + }; + +} // end namespace driver +} // end namespace clang + +#endif diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 7ecc38ad29..f464acf8eb 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -20,5 +20,3 @@ Driver::~Driver() { Compilation *Driver::BuildCompilation(int argc, const char **argv) { return new Compilation(); } - - diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp new file mode 100644 index 0000000000..46b5c41555 --- /dev/null +++ b/lib/Driver/Option.cpp @@ -0,0 +1,89 @@ +//===--- Option.cpp - Abstract Driver Options ---------------------------*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Driver/Option.h" +#include +using namespace clang; +using namespace clang::driver; + +Option::Option(OptionClass _Kind, const char *_Name, + OptionGroup *_Group, Option *_Alias) + : Kind(_Kind), Name(_Name), 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."); +} + +bool Option::matches(const Option *Opt) const { + // Aliases are never considered in matching. + if (Opt->getAlias()) + return matches(Opt->getAlias()); + if (Alias) + return Alias->matches(Opt); + + if (this == Opt) + return true; + + if (Group) + return Group->matches(Opt); + return false; +} + +OptionGroup::OptionGroup(const char *Name, OptionGroup *Group) + : Option(Option::GroupOption, Name, Group, 0) { +} + +InputOption::InputOption() + : Option(Option::InputOption, "", 0, 0) { +} + +UnknownOption::UnknownOption() + : Option(Option::UnknownOption, "", 0, 0) { +} + +FlagOption::FlagOption(const char *Name, OptionGroup *Group, Option *Alias) + : Option(Option::FlagOption, Name, Group, Alias) { +} + + +JoinedOption::JoinedOption(const char *Name, OptionGroup *Group, Option *Alias) + : Option(Option::JoinedOption, Name, Group, Alias) { +} + +CommaJoinedOption::CommaJoinedOption(const char *Name, OptionGroup *Group, + Option *Alias) + : Option(Option::CommaJoinedOption, Name, Group, Alias) { +} + +SeparateOption::SeparateOption(const char *Name, OptionGroup *Group, + Option *Alias) + : Option(Option::SeparateOption, Name, Group, Alias) { +} + +MultiArgOption::MultiArgOption(const char *Name, OptionGroup *Group, + Option *Alias, unsigned _NumArgs) + : Option(Option::MultiArgOption, Name, Group, Alias), NumArgs(_NumArgs) { +} + +JoinedOrSeparateOption::JoinedOrSeparateOption(const char *Name, + OptionGroup *Group, + Option *Alias) + : Option(Option::JoinedOrSeparateOption, Name, Group, Alias) { +} + +JoinedAndSeparateOption::JoinedAndSeparateOption(const char *Name, + OptionGroup *Group, + Option *Alias) + : Option(Option::JoinedAndSeparateOption, Name, Group, Alias) { +} + + diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index 7c01e9b49b..919a870907 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This is the entry point to the clang driver; it is a thin -// wrapper for functionality in the Driver clang library. +// This is the entry point to the clang driver; it is a thin wrapper +// for functionality in the Driver clang library. // //===----------------------------------------------------------------------===//