1 //===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef CLANG_DRIVER_OPTION_H_
11 #define CLANG_DRIVER_OPTION_H_
13 #include "clang/Driver/OptSpecifier.h"
14 #include "llvm/Support/Casting.h"
17 using llvm::cast_or_null;
19 using llvm::dyn_cast_or_null;
27 /// Option - Abstract representation for a single form of driver
30 /// An Option class represents a form of option that the driver
31 /// takes, for example how many arguments the option has and how
32 /// they can be provided. Individual option instances store
33 /// additional information about what group the option is a member
34 /// of (if any), if the option is an alias, and a number of
35 /// flags. At runtime the driver parses the command line into
36 /// concrete Arg instances, each of which corresponds to a
37 /// particular Option instance.
49 JoinedOrSeparateClass,
50 JoinedAndSeparateClass
53 enum RenderStyleKind {
54 RenderCommaJoinedStyle,
69 /// Group this option is a member of, if any.
70 const OptionGroup *Group;
72 /// Option that this is an alias for, if any.
75 /// Unsupported options will be rejected.
78 /// Treat this option like a linker input?
81 /// When rendering as an input, don't render the option.
83 // FIXME: We should ditch the render/renderAsInput distinction.
84 bool NoOptAsInput : 1;
86 /// The style to using when rendering arguments parsed by this option.
87 unsigned RenderStyle : 2;
89 /// This option is only consumed by the driver.
90 bool DriverOption : 1;
92 /// This option should not report argument unused errors.
93 bool NoArgumentUnused : 1;
95 /// This option should not be implicitly forwarded.
99 Option(OptionClass Kind, OptSpecifier ID, const char *Name,
100 const OptionGroup *Group, const Option *Alias);
104 unsigned getID() const { return ID.getID(); }
105 OptionClass getKind() const { return Kind; }
106 const char *getName() const { return Name; }
107 const OptionGroup *getGroup() const { return Group; }
108 const Option *getAlias() const { return Alias; }
110 bool isUnsupported() const { return Unsupported; }
111 void setUnsupported(bool Value) { Unsupported = Value; }
113 bool isLinkerInput() const { return LinkerInput; }
114 void setLinkerInput(bool Value) { LinkerInput = Value; }
116 bool hasNoOptAsInput() const { return NoOptAsInput; }
117 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
119 RenderStyleKind getRenderStyle() const {
120 return RenderStyleKind(RenderStyle);
122 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
124 bool isDriverOption() const { return DriverOption; }
125 void setDriverOption(bool Value) { DriverOption = Value; }
127 bool hasNoArgumentUnused() const { return NoArgumentUnused; }
128 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
130 bool hasNoForward() const { return NoForward; }
131 void setNoForward(bool Value) { NoForward = Value; }
133 bool hasForwardToGCC() const {
134 return !NoForward && !DriverOption && !LinkerInput;
137 /// getUnaliasedOption - Return the final option this option
138 /// aliases (itself, if the option has no alias).
139 const Option *getUnaliasedOption() const {
140 if (Alias) return Alias->getUnaliasedOption();
144 /// getRenderName - Return the name to use when rendering this
146 const char *getRenderName() const {
147 return getUnaliasedOption()->getName();
150 /// matches - Predicate for whether this option is part of the
151 /// given option (which may be a group).
153 /// Note that matches against options which are an alias should never be
154 /// done -- aliases do not participate in matching and so such a query will
156 bool matches(OptSpecifier ID) const;
158 /// accept - Potentially accept the current argument, returning a
159 /// new Arg instance, or 0 if the option does not accept this
160 /// argument (or the argument is missing values).
162 /// If the option accepts the current argument, accept() sets
163 /// Index to the position where argument parsing should resume
164 /// (even if the argument is missing values).
165 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
169 static bool classof(const Option *) { return true; }
172 /// OptionGroup - A set of options which are can be handled uniformly
174 class OptionGroup : public Option {
176 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
178 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
180 static bool classof(const Option *O) {
181 return O->getKind() == Option::GroupClass;
183 static bool classof(const OptionGroup *) { return true; }
186 // Dummy option classes.
188 /// InputOption - Dummy option class for representing driver inputs.
189 class InputOption : public Option {
191 InputOption(OptSpecifier ID);
193 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
195 static bool classof(const Option *O) {
196 return O->getKind() == Option::InputClass;
198 static bool classof(const InputOption *) { return true; }
201 /// UnknownOption - Dummy option class for represent unknown arguments.
202 class UnknownOption : public Option {
204 UnknownOption(OptSpecifier ID);
206 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
208 static bool classof(const Option *O) {
209 return O->getKind() == Option::UnknownClass;
211 static bool classof(const UnknownOption *) { return true; }
216 class FlagOption : public Option {
218 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
219 const Option *Alias);
221 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
223 static bool classof(const Option *O) {
224 return O->getKind() == Option::FlagClass;
226 static bool classof(const FlagOption *) { return true; }
229 class JoinedOption : public Option {
231 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
232 const Option *Alias);
234 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
236 static bool classof(const Option *O) {
237 return O->getKind() == Option::JoinedClass;
239 static bool classof(const JoinedOption *) { return true; }
242 class SeparateOption : public Option {
244 SeparateOption(OptSpecifier ID, const char *Name,
245 const OptionGroup *Group, const Option *Alias);
247 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
249 static bool classof(const Option *O) {
250 return O->getKind() == Option::SeparateClass;
252 static bool classof(const SeparateOption *) { return true; }
255 class CommaJoinedOption : public Option {
257 CommaJoinedOption(OptSpecifier ID, const char *Name,
258 const OptionGroup *Group, const Option *Alias);
260 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
262 static bool classof(const Option *O) {
263 return O->getKind() == Option::CommaJoinedClass;
265 static bool classof(const CommaJoinedOption *) { return true; }
268 // FIXME: Fold MultiArgOption into SeparateOption?
270 /// MultiArgOption - An option which takes multiple arguments (these
271 /// are always separate arguments).
272 class MultiArgOption : public Option {
276 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
277 const Option *Alias, unsigned NumArgs);
279 unsigned getNumArgs() const { return NumArgs; }
281 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
283 static bool classof(const Option *O) {
284 return O->getKind() == Option::MultiArgClass;
286 static bool classof(const MultiArgOption *) { return true; }
289 /// JoinedOrSeparateOption - An option which either literally
290 /// prefixes its (non-empty) value, or is follwed by a value.
291 class JoinedOrSeparateOption : public Option {
293 JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
294 const OptionGroup *Group, const Option *Alias);
296 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
298 static bool classof(const Option *O) {
299 return O->getKind() == Option::JoinedOrSeparateClass;
301 static bool classof(const JoinedOrSeparateOption *) { return true; }
304 /// JoinedAndSeparateOption - An option which literally prefixes its
305 /// value and is followed by another value.
306 class JoinedAndSeparateOption : public Option {
308 JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
309 const OptionGroup *Group, const Option *Alias);
311 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
313 static bool classof(const Option *O) {
314 return O->getKind() == Option::JoinedAndSeparateClass;
316 static bool classof(const JoinedAndSeparateOption *) { return true; }
319 } // end namespace driver
320 } // end namespace clang