Option.h revision 263508
126924Smsmith//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
226924Smsmith//
326924Smsmith//                     The LLVM Compiler Infrastructure
426924Smsmith//
526924Smsmith// This file is distributed under the University of Illinois Open Source
626924Smsmith// License. See LICENSE.TXT for details.
726924Smsmith//
826924Smsmith//===----------------------------------------------------------------------===//
926924Smsmith
1026924Smsmith#ifndef LLVM_OPTION_OPTION_H
1126924Smsmith#define LLVM_OPTION_OPTION_H
1226924Smsmith
1326924Smsmith#include "llvm/ADT/SmallVector.h"
1426924Smsmith#include "llvm/ADT/StringRef.h"
1526924Smsmith#include "llvm/Option/OptTable.h"
1626924Smsmith#include "llvm/Support/ErrorHandling.h"
1726924Smsmith
1826924Smsmithnamespace llvm {
1926924Smsmithnamespace opt {
2026924Smsmithclass Arg;
2126924Smsmithclass ArgList;
2226924Smsmith/// ArgStringList - Type used for constructing argv lists for subprocesses.
2326924Smsmithtypedef SmallVector<const char*, 16> ArgStringList;
2426924Smsmith
2526924Smsmith/// Base flags for all options. Custom flags may be added after.
2626924Smsmithenum DriverFlag {
2726924Smsmith  HelpHidden       = (1 << 0),
2826924Smsmith  RenderAsInput    = (1 << 1),
2926924Smsmith  RenderJoined     = (1 << 2),
3026924Smsmith  RenderSeparate   = (1 << 3)
3126924Smsmith};
3293032Simp
3393032Simp/// Option - Abstract representation for a single form of driver
3426924Smsmith/// argument.
3526924Smsmith///
3626924Smsmith/// An Option class represents a form of option that the driver
3726924Smsmith/// takes, for example how many arguments the option has and how
3826924Smsmith/// they can be provided. Individual option instances store
3926924Smsmith/// additional information about what group the option is a member
4026924Smsmith/// of (if any), if the option is an alias, and a number of
4126924Smsmith/// flags. At runtime the driver parses the command line into
4226924Smsmith/// concrete Arg instances, each of which corresponds to a
4326924Smsmith/// particular Option instance.
4426924Smsmithclass Option {
4526924Smsmithpublic:
4626924Smsmith  enum OptionClass {
4726924Smsmith    GroupClass = 0,
4826924Smsmith    InputClass,
4926924Smsmith    UnknownClass,
5026924Smsmith    FlagClass,
5193032Simp    JoinedClass,
52109508Sobrien    SeparateClass,
5393032Simp    RemainingArgsClass,
5493032Simp    CommaJoinedClass,
5526924Smsmith    MultiArgClass,
5626924Smsmith    JoinedOrSeparateClass,
5726924Smsmith    JoinedAndSeparateClass
58  };
59
60  enum RenderStyleKind {
61    RenderCommaJoinedStyle,
62    RenderJoinedStyle,
63    RenderSeparateStyle,
64    RenderValuesStyle
65  };
66
67protected:
68  const OptTable::Info *Info;
69  const OptTable *Owner;
70
71public:
72  Option(const OptTable::Info *Info, const OptTable *Owner);
73  ~Option();
74
75  bool isValid() const {
76    return Info != 0;
77  }
78
79  unsigned getID() const {
80    assert(Info && "Must have a valid info!");
81    return Info->ID;
82  }
83
84  OptionClass getKind() const {
85    assert(Info && "Must have a valid info!");
86    return OptionClass(Info->Kind);
87  }
88
89  /// \brief Get the name of this option without any prefix.
90  StringRef getName() const {
91    assert(Info && "Must have a valid info!");
92    return Info->Name;
93  }
94
95  const Option getGroup() const {
96    assert(Info && "Must have a valid info!");
97    assert(Owner && "Must have a valid owner!");
98    return Owner->getOption(Info->GroupID);
99  }
100
101  const Option getAlias() const {
102    assert(Info && "Must have a valid info!");
103    assert(Owner && "Must have a valid owner!");
104    return Owner->getOption(Info->AliasID);
105  }
106
107  /// \brief Get the alias arguments as a \0 separated list.
108  /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
109  const char *getAliasArgs() const {
110    assert(Info && "Must have a valid info!");
111    assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
112           "AliasArgs should be either 0 or non-empty.");
113
114    return Info->AliasArgs;
115  }
116
117  /// \brief Get the default prefix for this option.
118  StringRef getPrefix() const {
119    const char *Prefix = *Info->Prefixes;
120    return Prefix ? Prefix : StringRef();
121  }
122
123  /// \brief Get the name of this option with the default prefix.
124  std::string getPrefixedName() const {
125    std::string Ret = getPrefix();
126    Ret += getName();
127    return Ret;
128  }
129
130  unsigned getNumArgs() const { return Info->Param; }
131
132  bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
133
134  RenderStyleKind getRenderStyle() const {
135    if (Info->Flags & RenderJoined)
136      return RenderJoinedStyle;
137    if (Info->Flags & RenderSeparate)
138      return RenderSeparateStyle;
139    switch (getKind()) {
140    case GroupClass:
141    case InputClass:
142    case UnknownClass:
143      return RenderValuesStyle;
144    case JoinedClass:
145    case JoinedAndSeparateClass:
146      return RenderJoinedStyle;
147    case CommaJoinedClass:
148      return RenderCommaJoinedStyle;
149    case FlagClass:
150    case SeparateClass:
151    case MultiArgClass:
152    case JoinedOrSeparateClass:
153    case RemainingArgsClass:
154      return RenderSeparateStyle;
155    }
156    llvm_unreachable("Unexpected kind!");
157  }
158
159  /// Test if this option has the flag \a Val.
160  bool hasFlag(unsigned Val) const {
161    return Info->Flags & Val;
162  }
163
164  /// getUnaliasedOption - Return the final option this option
165  /// aliases (itself, if the option has no alias).
166  const Option getUnaliasedOption() const {
167    const Option Alias = getAlias();
168    if (Alias.isValid()) return Alias.getUnaliasedOption();
169    return *this;
170  }
171
172  /// getRenderName - Return the name to use when rendering this
173  /// option.
174  StringRef getRenderName() const {
175    return getUnaliasedOption().getName();
176  }
177
178  /// matches - Predicate for whether this option is part of the
179  /// given option (which may be a group).
180  ///
181  /// Note that matches against options which are an alias should never be
182  /// done -- aliases do not participate in matching and so such a query will
183  /// always be false.
184  bool matches(OptSpecifier ID) const;
185
186  /// accept - Potentially accept the current argument, returning a
187  /// new Arg instance, or 0 if the option does not accept this
188  /// argument (or the argument is missing values).
189  ///
190  /// If the option accepts the current argument, accept() sets
191  /// Index to the position where argument parsing should resume
192  /// (even if the argument is missing values).
193  ///
194  /// \param ArgSize The number of bytes taken up by the matched Option prefix
195  ///                and name. This is used to determine where joined values
196  ///                start.
197  Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
198
199  void dump() const;
200};
201
202} // end namespace opt
203} // end namespace llvm
204
205#endif
206