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.
94 /// CC1Option - This option should be accepted by clang -cc1.
98 Option(OptionClass Kind, OptSpecifier ID, const char *Name,
99 const OptionGroup *Group, const Option *Alias);
103 unsigned getID() const { return ID.getID(); }
104 OptionClass getKind() const { return Kind; }
105 StringRef getName() const { return Name; }
106 const OptionGroup *getGroup() const { return Group; }
107 const Option *getAlias() const { return Alias; }
109 bool isUnsupported() const { return Unsupported; }
110 void setUnsupported(bool Value) { Unsupported = Value; }
112 bool isLinkerInput() const { return LinkerInput; }
113 void setLinkerInput(bool Value) { LinkerInput = Value; }
115 bool hasNoOptAsInput() const { return NoOptAsInput; }
116 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
118 RenderStyleKind getRenderStyle() const {
119 return RenderStyleKind(RenderStyle);
121 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
123 bool isDriverOption() const { return DriverOption; }
124 void setDriverOption(bool Value) { DriverOption = Value; }
126 bool hasNoArgumentUnused() const { return NoArgumentUnused; }
127 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
129 bool hasNoForward() const { return NoForward; }
130 void setNoForward(bool Value) { NoForward = Value; }
132 bool isCC1Option() const { return CC1Option; }
133 void setIsCC1Option(bool Value) { CC1Option = Value; }
135 bool hasForwardToGCC() const {
136 return !NoForward && !DriverOption && !LinkerInput;
139 /// getUnaliasedOption - Return the final option this option
140 /// aliases (itself, if the option has no alias).
141 const Option *getUnaliasedOption() const {
142 if (Alias) return Alias->getUnaliasedOption();
146 /// getRenderName - Return the name to use when rendering this
148 StringRef getRenderName() const {
149 return getUnaliasedOption()->getName();
152 /// matches - Predicate for whether this option is part of the
153 /// given option (which may be a group).
155 /// Note that matches against options which are an alias should never be
156 /// done -- aliases do not participate in matching and so such a query will
158 bool matches(OptSpecifier ID) const;
160 /// accept - Potentially accept the current argument, returning a
161 /// new Arg instance, or 0 if the option does not accept this
162 /// argument (or the argument is missing values).
164 /// If the option accepts the current argument, accept() sets
165 /// Index to the position where argument parsing should resume
166 /// (even if the argument is missing values).
167 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
171 static bool classof(const Option *) { return true; }
174 /// OptionGroup - A set of options which are can be handled uniformly
176 class OptionGroup : public Option {
178 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
180 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
182 static bool classof(const Option *O) {
183 return O->getKind() == Option::GroupClass;
185 static bool classof(const OptionGroup *) { return true; }
188 // Dummy option classes.
190 /// InputOption - Dummy option class for representing driver inputs.
191 class InputOption : public Option {
193 InputOption(OptSpecifier ID);
195 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
197 static bool classof(const Option *O) {
198 return O->getKind() == Option::InputClass;
200 static bool classof(const InputOption *) { return true; }
203 /// UnknownOption - Dummy option class for represent unknown arguments.
204 class UnknownOption : public Option {
206 UnknownOption(OptSpecifier ID);
208 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
210 static bool classof(const Option *O) {
211 return O->getKind() == Option::UnknownClass;
213 static bool classof(const UnknownOption *) { return true; }
218 class FlagOption : public Option {
220 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
221 const Option *Alias);
223 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
225 static bool classof(const Option *O) {
226 return O->getKind() == Option::FlagClass;
228 static bool classof(const FlagOption *) { return true; }
231 class JoinedOption : public Option {
233 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
234 const Option *Alias);
236 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
238 static bool classof(const Option *O) {
239 return O->getKind() == Option::JoinedClass;
241 static bool classof(const JoinedOption *) { return true; }
244 class SeparateOption : public Option {
246 SeparateOption(OptSpecifier ID, const char *Name,
247 const OptionGroup *Group, const Option *Alias);
249 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
251 static bool classof(const Option *O) {
252 return O->getKind() == Option::SeparateClass;
254 static bool classof(const SeparateOption *) { return true; }
257 class CommaJoinedOption : public Option {
259 CommaJoinedOption(OptSpecifier ID, const char *Name,
260 const OptionGroup *Group, const Option *Alias);
262 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
264 static bool classof(const Option *O) {
265 return O->getKind() == Option::CommaJoinedClass;
267 static bool classof(const CommaJoinedOption *) { return true; }
270 // FIXME: Fold MultiArgOption into SeparateOption?
272 /// MultiArgOption - An option which takes multiple arguments (these
273 /// are always separate arguments).
274 class MultiArgOption : public Option {
278 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
279 const Option *Alias, unsigned NumArgs);
281 unsigned getNumArgs() const { return NumArgs; }
283 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
285 static bool classof(const Option *O) {
286 return O->getKind() == Option::MultiArgClass;
288 static bool classof(const MultiArgOption *) { return true; }
291 /// JoinedOrSeparateOption - An option which either literally
292 /// prefixes its (non-empty) value, or is follwed by a value.
293 class JoinedOrSeparateOption : public Option {
295 JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
296 const OptionGroup *Group, const Option *Alias);
298 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
300 static bool classof(const Option *O) {
301 return O->getKind() == Option::JoinedOrSeparateClass;
303 static bool classof(const JoinedOrSeparateOption *) { return true; }
306 /// JoinedAndSeparateOption - An option which literally prefixes its
307 /// value and is followed by another value.
308 class JoinedAndSeparateOption : public Option {
310 JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
311 const OptionGroup *Group, const Option *Alias);
313 virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
315 static bool classof(const Option *O) {
316 return O->getKind() == Option::JoinedAndSeparateClass;
318 static bool classof(const JoinedAndSeparateOption *) { return true; }
321 } // end namespace driver
322 } // end namespace clang