diff options
Diffstat (limited to 'include/clang/Driver/Arg.h')
-rw-r--r-- | include/clang/Driver/Arg.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h new file mode 100644 index 0000000..6bed2b8 --- /dev/null +++ b/include/clang/Driver/Arg.h @@ -0,0 +1,230 @@ +//===--- Arg.h - Parsed Argument Classes ------------------------*- 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_ARG_H_ +#define CLANG_DRIVER_ARG_H_ + +#include "llvm/Support/Casting.h" +using llvm::isa; +using llvm::cast; +using llvm::cast_or_null; +using llvm::dyn_cast; +using llvm::dyn_cast_or_null; + +#include "Util.h" +#include <vector> +#include <string> + +namespace clang { +namespace driver { + class ArgList; + class Option; + + /// Arg - A concrete instance of a particular driver option. + /// + /// The Arg class encodes just enough information to be able to + /// derive the argument values efficiently. In addition, Arg + /// instances have an intrusive double linked list which is used by + /// ArgList to provide efficient iteration over all instances of a + /// particular option. + class Arg { + public: + enum ArgClass { + FlagClass = 0, + PositionalClass, + JoinedClass, + SeparateClass, + CommaJoinedClass, + JoinedAndSeparateClass + }; + + private: + ArgClass Kind; + + /// The option this argument is an instance of. + const Option *Opt; + + /// The argument this argument was derived from (during tool chain + /// argument translation), if any. + const Arg *BaseArg; + + /// The index at which this argument appears in the containing + /// ArgList. + unsigned Index; + + /// Flag indicating whether this argument was used to effect + /// compilation; used for generating "argument unused" + /// diagnostics. + mutable bool Claimed; + + protected: + Arg(ArgClass Kind, const Option *Opt, unsigned Index, + const Arg *BaseArg = 0); + + public: + Arg(const Arg &); + virtual ~Arg(); + + ArgClass getKind() const { return Kind; } + const Option &getOption() const { return *Opt; } + unsigned getIndex() const { return Index; } + + /// getBaseArg - Return the base argument which generated this + /// arg; this is either the argument itself or the argument it was + /// derived from during tool chain specific argument translation. + const Arg &getBaseArg() const { + return BaseArg ? *BaseArg : *this; + } + void setBaseArg(const Arg *_BaseArg) { + BaseArg = _BaseArg; + } + + bool isClaimed() const { return getBaseArg().Claimed; } + + /// claim - Set the Arg claimed bit. + + // FIXME: We need to deal with derived arguments and set the bit + // in the original argument; not the derived one. + void claim() const { getBaseArg().Claimed = true; } + + virtual unsigned getNumValues() const = 0; + virtual const char *getValue(const ArgList &Args, unsigned N=0) const = 0; + + /// render - Append the argument onto the given array as strings. + virtual void render(const ArgList &Args, ArgStringList &Output) const = 0; + + /// renderAsInput - Append the argument, render as an input, onto + /// the given array as strings. The distinction is that some + /// options only render their values when rendered as a input + /// (e.g., Xlinker). + void renderAsInput(const ArgList &Args, ArgStringList &Output) const; + + static bool classof(const Arg *) { return true; } + + void dump() const; + + /// getAsString - Return a formatted version of the argument and + /// its values, for debugging and diagnostics. + std::string getAsString(const ArgList &Args) const; + }; + + /// FlagArg - An argument with no value. + class FlagArg : public Arg { + public: + FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return 0; } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::FlagClass; + } + static bool classof(const FlagArg *) { return true; } + }; + + /// PositionalArg - A simple positional argument. + class PositionalArg : public Arg { + public: + PositionalArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return 1; } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::PositionalClass; + } + static bool classof(const PositionalArg *) { return true; } + }; + + /// JoinedArg - A single value argument where the value is joined + /// (suffixed) to the option. + class JoinedArg : public Arg { + public: + JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return 1; } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::JoinedClass; + } + static bool classof(const JoinedArg *) { return true; } + }; + + /// SeparateArg - An argument where one or more values follow the + /// option specifier immediately in the argument vector. + class SeparateArg : public Arg { + unsigned NumValues; + + public: + SeparateArg(const Option *Opt, unsigned Index, unsigned NumValues, + const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return NumValues; } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::SeparateClass; + } + static bool classof(const SeparateArg *) { return true; } + }; + + /// CommaJoinedArg - An argument with multiple values joined by + /// commas and joined (suffixed) to the option specifier. + /// + /// The key point of this arg is that it renders its values into + /// separate arguments, which allows it to be used as a generic + /// mechanism for passing arguments through to tools. + class CommaJoinedArg : public Arg { + std::vector<std::string> Values; + + public: + CommaJoinedArg(const Option *Opt, unsigned Index, const char *Str, + const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return Values.size(); } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::CommaJoinedClass; + } + static bool classof(const CommaJoinedArg *) { return true; } + }; + + /// JoinedAndSeparateArg - An argument with both joined and separate + /// values. + class JoinedAndSeparateArg : public Arg { + public: + JoinedAndSeparateArg(const Option *Opt, unsigned Index, + const Arg *BaseArg = 0); + + virtual void render(const ArgList &Args, ArgStringList &Output) const; + + virtual unsigned getNumValues() const { return 2; } + virtual const char *getValue(const ArgList &Args, unsigned N=0) const; + + static bool classof(const Arg *A) { + return A->getKind() == Arg::JoinedAndSeparateClass; + } + static bool classof(const JoinedAndSeparateArg *) { return true; } + }; +} // end namespace driver +} // end namespace clang + +#endif |