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 "llvm/Support/Casting.h"
18 using llvm::cast_or_null;
20 using llvm::dyn_cast_or_null;
28 /// Option - Abstract representation for a single form of driver
31 /// An Option class represents a form of option that the driver
32 /// takes, for example how many arguments the option has and how
33 /// they can be provided. Individual option instances store
34 /// additional information about what group the option is a member
35 /// of (if any), if the option is an alias, and a number of
36 /// flags. At runtime the driver parses the command line into
37 /// concrete Arg instances, each of which corresponds to a
38 /// particular Option instance.
50 JoinedOrSeparateClass,
51 JoinedAndSeparateClass
54 enum RenderStyleKind {
55 RenderCommaJoinedStyle,
70 /// Group this option is a member of, if any.
71 const OptionGroup *Group;
73 /// Option that this is an alias for, if any.
76 /// Unsupported options will be rejected.
79 /// Treat this option like a linker input?
82 /// When rendering as an input, don't render the option.
84 // FIXME: We should ditch the render/renderAsInput distinction.
85 bool NoOptAsInput : 1;
87 /// The style to using when rendering arguments parsed by this option.
88 unsigned RenderStyle : 2;
90 /// This option is only consumed by the driver.
91 bool DriverOption : 1;
93 /// This option should not report argument unused errors.
94 bool NoArgumentUnused : 1;
96 /// This option should not be implicitly forwarded.
100 Option(OptionClass Kind, OptSpecifier ID, const char *Name,
101 const OptionGroup *Group, const Option *Alias);
105 unsigned getID() const { return ID.getID(); }
106 OptionClass getKind() const { return Kind; }
107 llvm::StringRef getName() const { return Name; }
108 const OptionGroup *getGroup() const { return Group; }
109 const Option *getAlias() const { return Alias; }
111 bool isUnsupported() const { return Unsupported; }
112 void setUnsupported(bool Value) { Unsupported = Value; }
114 bool isLinkerInput() const { return LinkerInput; }
115 void setLinkerInput(bool Value) { LinkerInput = Value; }
117 bool hasNoOptAsInput() const { return NoOptAsInput; }
118 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
120 RenderStyleKind getRenderStyle() const {
121 return RenderStyleKind(RenderStyle);
123 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
125 bool isDriverOption() const { return DriverOption; }
126 void setDriverOption(bool Value) { DriverOption = Value; }
128 bool hasNoArgumentUnused() const { return NoArgumentUnused; }
129 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
131 bool hasNoForward() const { return NoForward; }
132 void setNoForward(bool Value) { NoForward = Value; }
134 bool hasForwardToGCC() const {
135 return !NoForward && !DriverOption && !LinkerInput;
138 /// getUnaliasedOption - Return the final option this option
139 /// aliases (itself, if the option has no alias).
140 const Option *getUnaliasedOption() const {
141 if (Alias) return Alias->getUnaliasedOption();
145 /// getRenderName - Return the name to use when rendering this
147 llvm::StringRef getRenderName() const {
148 return getUnaliasedOption()->getName();
151 /// matches - Predicate for whether this option is part of the
152 /// given option (which may be a group).
154 /// Note that matches against options which are an alias should never be
155 /// done -- aliases do not participate in matching and so such a query will
157 bool matches(OptSpecifier ID) const;
159 /// accept - Potentially accept the current argument, returning a
160 /// new Arg instance, or 0 if the option does not accept this
161 /// argument (or the argument is missing values).
163 /// If the option accepts the current argument, accept() sets
164 /// Index to the position where argument parsing should resume
165 /// (even if the argument is missing values).
166 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
170 static bool classof(const Option *) { return true; }
173 /// OptionGroup - A set of options which are can be handled uniformly
175 class OptionGroup : public Option {
177 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
179 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
181 static bool classof(const Option *O) {
182 return O->getKind() == Option::GroupClass;
184 static bool classof(const OptionGroup *) { return true; }
187 // Dummy option classes.
189 /// InputOption - Dummy option class for representing driver inputs.
190 class InputOption : public Option {
192 InputOption(OptSpecifier ID);
194 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
196 static bool classof(const Option *O) {
197 return O->getKind() == Option::InputClass;
199 static bool classof(const InputOption *) { return true; }
202 /// UnknownOption - Dummy option class for represent unknown arguments.
203 class UnknownOption : public Option {
205 UnknownOption(OptSpecifier ID);
207 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
209 static bool classof(const Option *O) {
210 return O->getKind() == Option::UnknownClass;
212 static bool classof(const UnknownOption *) { return true; }
217 class FlagOption : public Option {
219 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
220 const Option *Alias);
222 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
224 static bool classof(const Option *O) {
225 return O->getKind() == Option::FlagClass;
227 static bool classof(const FlagOption *) { return true; }
230 class JoinedOption : public Option {
232 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
233 const Option *Alias);
235 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
237 static bool classof(const Option *O) {
238 return O->getKind() == Option::JoinedClass;
240 static bool classof(const JoinedOption *) { return true; }
243 class SeparateOption : public Option {
245 SeparateOption(OptSpecifier ID, const char *Name,
246 const OptionGroup *Group, const Option *Alias);
248 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
250 static bool classof(const Option *O) {
251 return O->getKind() == Option::SeparateClass;
253 static bool classof(const SeparateOption *) { return true; }
256 class CommaJoinedOption : public Option {
258 CommaJoinedOption(OptSpecifier ID, const char *Name,
259 const OptionGroup *Group, const Option *Alias);
261 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
263 static bool classof(const Option *O) {
264 return O->getKind() == Option::CommaJoinedClass;
266 static bool classof(const CommaJoinedOption *) { return true; }
269 // FIXME: Fold MultiArgOption into SeparateOption?
271 /// MultiArgOption - An option which takes multiple arguments (these
272 /// are always separate arguments).
273 class MultiArgOption : public Option {
277 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
278 const Option *Alias, unsigned NumArgs);
280 unsigned getNumArgs() const { return NumArgs; }
282 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
284 static bool classof(const Option *O) {
285 return O->getKind() == Option::MultiArgClass;
287 static bool classof(const MultiArgOption *) { return true; }
290 /// JoinedOrSeparateOption - An option which either literally
291 /// prefixes its (non-empty) value, or is follwed by a value.
292 class JoinedOrSeparateOption : public Option {
294 JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
295 const OptionGroup *Group, const Option *Alias);
297 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
299 static bool classof(const Option *O) {
300 return O->getKind() == Option::JoinedOrSeparateClass;
302 static bool classof(const JoinedOrSeparateOption *) { return true; }
305 /// JoinedAndSeparateOption - An option which literally prefixes its
306 /// value and is followed by another value.
307 class JoinedAndSeparateOption : public Option {
309 JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
310 const OptionGroup *Group, const Option *Alias);
312 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
314 static bool classof(const Option *O) {
315 return O->getKind() == Option::JoinedAndSeparateClass;
317 static bool classof(const JoinedAndSeparateOption *) { return true; }
320 } // end namespace driver
321 } // end namespace clang