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