]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Driver/Option.h
Update dialog to 1.1-20110707.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Driver / Option.h
1 //===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef CLANG_DRIVER_OPTION_H_
11 #define CLANG_DRIVER_OPTION_H_
12
13 #include "clang/Driver/OptSpecifier.h"
14 #include "llvm/Support/Casting.h"
15 using llvm::isa;
16 using llvm::cast;
17 using llvm::cast_or_null;
18 using llvm::dyn_cast;
19 using llvm::dyn_cast_or_null;
20
21 namespace clang {
22 namespace driver {
23   class Arg;
24   class ArgList;
25   class OptionGroup;
26
27   /// Option - Abstract representation for a single form of driver
28   /// argument.
29   ///
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.
38   class Option {
39   public:
40     enum OptionClass {
41       GroupClass = 0,
42       InputClass,
43       UnknownClass,
44       FlagClass,
45       JoinedClass,
46       SeparateClass,
47       CommaJoinedClass,
48       MultiArgClass,
49       JoinedOrSeparateClass,
50       JoinedAndSeparateClass
51     };
52
53     enum RenderStyleKind {
54       RenderCommaJoinedStyle,
55       RenderJoinedStyle,
56       RenderSeparateStyle,
57       RenderValuesStyle
58     };
59
60   private:
61     OptionClass Kind;
62
63     /// The option ID.
64     OptSpecifier ID;
65
66     /// The option name.
67     const char *Name;
68
69     /// Group this option is a member of, if any.
70     const OptionGroup *Group;
71
72     /// Option that this is an alias for, if any.
73     const Option *Alias;
74
75     /// Unsupported options will be rejected.
76     bool Unsupported : 1;
77
78     /// Treat this option like a linker input?
79     bool LinkerInput : 1;
80
81     /// When rendering as an input, don't render the option.
82
83     // FIXME: We should ditch the render/renderAsInput distinction.
84     bool NoOptAsInput : 1;
85
86     /// The style to using when rendering arguments parsed by this option.
87     unsigned RenderStyle : 2;
88
89     /// This option is only consumed by the driver.
90     bool DriverOption : 1;
91
92     /// This option should not report argument unused errors.
93     bool NoArgumentUnused : 1;
94
95     /// This option should not be implicitly forwarded.
96     bool NoForward : 1;
97
98   protected:
99     Option(OptionClass Kind, OptSpecifier ID, const char *Name,
100            const OptionGroup *Group, const Option *Alias);
101   public:
102     virtual ~Option();
103
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; }
109
110     bool isUnsupported() const { return Unsupported; }
111     void setUnsupported(bool Value) { Unsupported = Value; }
112
113     bool isLinkerInput() const { return LinkerInput; }
114     void setLinkerInput(bool Value) { LinkerInput = Value; }
115
116     bool hasNoOptAsInput() const { return NoOptAsInput; }
117     void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
118
119     RenderStyleKind getRenderStyle() const {
120       return RenderStyleKind(RenderStyle);
121     }
122     void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
123
124     bool isDriverOption() const { return DriverOption; }
125     void setDriverOption(bool Value) { DriverOption = Value; }
126
127     bool hasNoArgumentUnused() const { return NoArgumentUnused; }
128     void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
129
130     bool hasNoForward() const { return NoForward; }
131     void setNoForward(bool Value) { NoForward = Value; }
132
133     bool hasForwardToGCC() const {
134       return !NoForward && !DriverOption && !LinkerInput;
135     }
136
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();
141       return this;
142     }
143
144     /// getRenderName - Return the name to use when rendering this
145     /// option.
146     const char *getRenderName() const {
147       return getUnaliasedOption()->getName();
148     }
149
150     /// matches - Predicate for whether this option is part of the
151     /// given option (which may be a group).
152     ///
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
155     /// always be false.
156     bool matches(OptSpecifier ID) const;
157
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).
161     ///
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;
166
167     void dump() const;
168
169     static bool classof(const Option *) { return true; }
170   };
171
172   /// OptionGroup - A set of options which are can be handled uniformly
173   /// by the driver.
174   class OptionGroup : public Option {
175   public:
176     OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
177
178     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
179
180     static bool classof(const Option *O) {
181       return O->getKind() == Option::GroupClass;
182     }
183     static bool classof(const OptionGroup *) { return true; }
184   };
185
186   // Dummy option classes.
187
188   /// InputOption - Dummy option class for representing driver inputs.
189   class InputOption : public Option {
190   public:
191     InputOption(OptSpecifier ID);
192
193     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
194
195     static bool classof(const Option *O) {
196       return O->getKind() == Option::InputClass;
197     }
198     static bool classof(const InputOption *) { return true; }
199   };
200
201   /// UnknownOption - Dummy option class for represent unknown arguments.
202   class UnknownOption : public Option {
203   public:
204     UnknownOption(OptSpecifier ID);
205
206     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
207
208     static bool classof(const Option *O) {
209       return O->getKind() == Option::UnknownClass;
210     }
211     static bool classof(const UnknownOption *) { return true; }
212   };
213
214   // Normal options.
215
216   class FlagOption : public Option {
217   public:
218     FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
219                const Option *Alias);
220
221     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
222
223     static bool classof(const Option *O) {
224       return O->getKind() == Option::FlagClass;
225     }
226     static bool classof(const FlagOption *) { return true; }
227   };
228
229   class JoinedOption : public Option {
230   public:
231     JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
232                  const Option *Alias);
233
234     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
235
236     static bool classof(const Option *O) {
237       return O->getKind() == Option::JoinedClass;
238     }
239     static bool classof(const JoinedOption *) { return true; }
240   };
241
242   class SeparateOption : public Option {
243   public:
244     SeparateOption(OptSpecifier ID, const char *Name,
245                    const OptionGroup *Group, const Option *Alias);
246
247     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
248
249     static bool classof(const Option *O) {
250       return O->getKind() == Option::SeparateClass;
251     }
252     static bool classof(const SeparateOption *) { return true; }
253   };
254
255   class CommaJoinedOption : public Option {
256   public:
257     CommaJoinedOption(OptSpecifier ID, const char *Name,
258                       const OptionGroup *Group, const Option *Alias);
259
260     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
261
262     static bool classof(const Option *O) {
263       return O->getKind() == Option::CommaJoinedClass;
264     }
265     static bool classof(const CommaJoinedOption *) { return true; }
266   };
267
268   // FIXME: Fold MultiArgOption into SeparateOption?
269
270   /// MultiArgOption - An option which takes multiple arguments (these
271   /// are always separate arguments).
272   class MultiArgOption : public Option {
273     unsigned NumArgs;
274
275   public:
276     MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
277                    const Option *Alias, unsigned NumArgs);
278
279     unsigned getNumArgs() const { return NumArgs; }
280
281     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
282
283     static bool classof(const Option *O) {
284       return O->getKind() == Option::MultiArgClass;
285     }
286     static bool classof(const MultiArgOption *) { return true; }
287   };
288
289   /// JoinedOrSeparateOption - An option which either literally
290   /// prefixes its (non-empty) value, or is follwed by a value.
291   class JoinedOrSeparateOption : public Option {
292   public:
293     JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
294                            const OptionGroup *Group, const Option *Alias);
295
296     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
297
298     static bool classof(const Option *O) {
299       return O->getKind() == Option::JoinedOrSeparateClass;
300     }
301     static bool classof(const JoinedOrSeparateOption *) { return true; }
302   };
303
304   /// JoinedAndSeparateOption - An option which literally prefixes its
305   /// value and is followed by another value.
306   class JoinedAndSeparateOption : public Option {
307   public:
308     JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
309                             const OptionGroup *Group, const Option *Alias);
310
311     virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
312
313     static bool classof(const Option *O) {
314       return O->getKind() == Option::JoinedAndSeparateClass;
315     }
316     static bool classof(const JoinedAndSeparateOption *) { return true; }
317   };
318
319 } // end namespace driver
320 } // end namespace clang
321
322 #endif