//===--- 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 #include 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 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