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