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/ADT/StringRef.h"
15 #include "clang/Basic/LLVM.h"
23 /// Option - Abstract representation for a single form of driver
26 /// An Option class represents a form of option that the driver
27 /// takes, for example how many arguments the option has and how
28 /// they can be provided. Individual option instances store
29 /// additional information about what group the option is a member
30 /// of (if any), if the option is an alias, and a number of
31 /// flags. At runtime the driver parses the command line into
32 /// concrete Arg instances, each of which corresponds to a
33 /// particular Option instance.
45 JoinedOrSeparateClass,
46 JoinedAndSeparateClass
49 enum RenderStyleKind {
50 RenderCommaJoinedStyle,
65 /// Group this option is a member of, if any.
66 const OptionGroup *Group;
68 /// Option that this is an alias for, if any.
71 /// Unsupported options will be rejected.
74 /// Treat this option like a linker input?
77 /// When rendering as an input, don't render the option.
79 // FIXME: We should ditch the render/renderAsInput distinction.
80 bool NoOptAsInput : 1;
82 /// The style to using when rendering arguments parsed by this option.
83 unsigned RenderStyle : 2;
85 /// This option is only consumed by the driver.
86 bool DriverOption : 1;
88 /// This option should not report argument unused errors.
89 bool NoArgumentUnused : 1;
91 /// This option should not be implicitly forwarded.
95 Option(OptionClass Kind, OptSpecifier ID, const char *Name,
96 const OptionGroup *Group, const Option *Alias);
100 unsigned getID() const { return ID.getID(); }
101 OptionClass getKind() const { return Kind; }
102 StringRef getName() const { return Name; }
103 const OptionGroup *getGroup() const { return Group; }
104 const Option *getAlias() const { return Alias; }
106 bool isUnsupported() const { return Unsupported; }
107 void setUnsupported(bool Value) { Unsupported = Value; }
109 bool isLinkerInput() const { return LinkerInput; }
110 void setLinkerInput(bool Value) { LinkerInput = Value; }
112 bool hasNoOptAsInput() const { return NoOptAsInput; }
113 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
115 RenderStyleKind getRenderStyle() const {
116 return RenderStyleKind(RenderStyle);
118 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
120 bool isDriverOption() const { return DriverOption; }
121 void setDriverOption(bool Value) { DriverOption = Value; }
123 bool hasNoArgumentUnused() const { return NoArgumentUnused; }
124 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
126 bool hasNoForward() const { return NoForward; }
127 void setNoForward(bool Value) { NoForward = Value; }
129 bool hasForwardToGCC() const {
130 return !NoForward && !DriverOption && !LinkerInput;
133 /// getUnaliasedOption - Return the final option this option
134 /// aliases (itself, if the option has no alias).
135 const Option *getUnaliasedOption() const {
136 if (Alias) return Alias->getUnaliasedOption();
140 /// getRenderName - Return the name to use when rendering this
142 StringRef getRenderName() const {
143 return getUnaliasedOption()->getName();
146 /// matches - Predicate for whether this option is part of the
147 /// given option (which may be a group).
149 /// Note that matches against options which are an alias should never be
150 /// done -- aliases do not participate in matching and so such a query will
152 bool matches(OptSpecifier ID) const;
154 /// accept - Potentially accept the current argument, returning a
155 /// new Arg instance, or 0 if the option does not accept this
156 /// argument (or the argument is missing values).
158 /// If the option accepts the current argument, accept() sets
159 /// Index to the position where argument parsing should resume
160 /// (even if the argument is missing values).
161 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
165 static bool classof(const Option *) { return true; }
168 /// OptionGroup - A set of options which are can be handled uniformly
170 class OptionGroup : public Option {
172 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
174 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
176 static bool classof(const Option *O) {
177 return O->getKind() == Option::GroupClass;
179 static bool classof(const OptionGroup *) { return true; }
182 // Dummy option classes.
184 /// InputOption - Dummy option class for representing driver inputs.
185 class InputOption : public Option {
187 InputOption(OptSpecifier ID);
189 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
191 static bool classof(const Option *O) {
192 return O->getKind() == Option::InputClass;
194 static bool classof(const InputOption *) { return true; }
197 /// UnknownOption - Dummy option class for represent unknown arguments.
198 class UnknownOption : public Option {
200 UnknownOption(OptSpecifier ID);
202 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
204 static bool classof(const Option *O) {
205 return O->getKind() == Option::UnknownClass;
207 static bool classof(const UnknownOption *) { return true; }
212 class FlagOption : public Option {
214 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
215 const Option *Alias);
217 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
219 static bool classof(const Option *O) {
220 return O->getKind() == Option::FlagClass;
222 static bool classof(const FlagOption *) { return true; }
225 class JoinedOption : public Option {
227 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
228 const Option *Alias);
230 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
232 static bool classof(const Option *O) {
233 return O->getKind() == Option::JoinedClass;
235 static bool classof(const JoinedOption *) { return true; }
238 class SeparateOption : public Option {
240 SeparateOption(OptSpecifier ID, const char *Name,
241 const OptionGroup *Group, const Option *Alias);
243 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
245 static bool classof(const Option *O) {
246 return O->getKind() == Option::SeparateClass;
248 static bool classof(const SeparateOption *) { return true; }
251 class CommaJoinedOption : public Option {
253 CommaJoinedOption(OptSpecifier ID, const char *Name,
254 const OptionGroup *Group, const Option *Alias);
256 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
258 static bool classof(const Option *O) {
259 return O->getKind() == Option::CommaJoinedClass;
261 static bool classof(const CommaJoinedOption *) { return true; }
264 // FIXME: Fold MultiArgOption into SeparateOption?
266 /// MultiArgOption - An option which takes multiple arguments (these
267 /// are always separate arguments).
268 class MultiArgOption : public Option {
272 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
273 const Option *Alias, unsigned NumArgs);
275 unsigned getNumArgs() const { return NumArgs; }
277 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
279 static bool classof(const Option *O) {
280 return O->getKind() == Option::MultiArgClass;
282 static bool classof(const MultiArgOption *) { return true; }
285 /// JoinedOrSeparateOption - An option which either literally
286 /// prefixes its (non-empty) value, or is follwed by a value.
287 class JoinedOrSeparateOption : public Option {
289 JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
290 const OptionGroup *Group, const Option *Alias);
292 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
294 static bool classof(const Option *O) {
295 return O->getKind() == Option::JoinedOrSeparateClass;
297 static bool classof(const JoinedOrSeparateOption *) { return true; }
300 /// JoinedAndSeparateOption - An option which literally prefixes its
301 /// value and is followed by another value.
302 class JoinedAndSeparateOption : public Option {
304 JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
305 const OptionGroup *Group, const Option *Alias);
307 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
309 static bool classof(const Option *O) {
310 return O->getKind() == Option::JoinedAndSeparateClass;
312 static bool classof(const JoinedAndSeparateOption *) { return true; }
315 } // end namespace driver
316 } // end namespace clang