]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Option/Option.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Option / 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 LLVM_OPTION_OPTION_H
11 #define LLVM_OPTION_OPTION_H
12
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Option/OptSpecifier.h"
16 #include "llvm/Option/OptTable.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include <cassert>
19 #include <string>
20
21 namespace llvm {
22
23 class raw_ostream;
24
25 namespace opt {
26
27 class Arg;
28 class ArgList;
29
30 /// ArgStringList - Type used for constructing argv lists for subprocesses.
31 using ArgStringList = SmallVector<const char *, 16>;
32
33 /// Base flags for all options. Custom flags may be added after.
34 enum DriverFlag {
35   HelpHidden       = (1 << 0),
36   RenderAsInput    = (1 << 1),
37   RenderJoined     = (1 << 2),
38   RenderSeparate   = (1 << 3)
39 };
40
41 /// Option - Abstract representation for a single form of driver
42 /// argument.
43 ///
44 /// An Option class represents a form of option that the driver
45 /// takes, for example how many arguments the option has and how
46 /// they can be provided. Individual option instances store
47 /// additional information about what group the option is a member
48 /// of (if any), if the option is an alias, and a number of
49 /// flags. At runtime the driver parses the command line into
50 /// concrete Arg instances, each of which corresponds to a
51 /// particular Option instance.
52 class Option {
53 public:
54   enum OptionClass {
55     GroupClass = 0,
56     InputClass,
57     UnknownClass,
58     FlagClass,
59     JoinedClass,
60     ValuesClass,
61     SeparateClass,
62     RemainingArgsClass,
63     RemainingArgsJoinedClass,
64     CommaJoinedClass,
65     MultiArgClass,
66     JoinedOrSeparateClass,
67     JoinedAndSeparateClass
68   };
69
70   enum RenderStyleKind {
71     RenderCommaJoinedStyle,
72     RenderJoinedStyle,
73     RenderSeparateStyle,
74     RenderValuesStyle
75   };
76
77 protected:
78   const OptTable::Info *Info;
79   const OptTable *Owner;
80
81 public:
82   Option(const OptTable::Info *Info, const OptTable *Owner);
83
84   bool isValid() const {
85     return Info != nullptr;
86   }
87
88   unsigned getID() const {
89     assert(Info && "Must have a valid info!");
90     return Info->ID;
91   }
92
93   OptionClass getKind() const {
94     assert(Info && "Must have a valid info!");
95     return OptionClass(Info->Kind);
96   }
97
98   /// Get the name of this option without any prefix.
99   StringRef getName() const {
100     assert(Info && "Must have a valid info!");
101     return Info->Name;
102   }
103
104   const Option getGroup() const {
105     assert(Info && "Must have a valid info!");
106     assert(Owner && "Must have a valid owner!");
107     return Owner->getOption(Info->GroupID);
108   }
109
110   const Option getAlias() const {
111     assert(Info && "Must have a valid info!");
112     assert(Owner && "Must have a valid owner!");
113     return Owner->getOption(Info->AliasID);
114   }
115
116   /// Get the alias arguments as a \0 separated list.
117   /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
118   const char *getAliasArgs() const {
119     assert(Info && "Must have a valid info!");
120     assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
121            "AliasArgs should be either 0 or non-empty.");
122
123     return Info->AliasArgs;
124   }
125
126   /// Get the default prefix for this option.
127   StringRef getPrefix() const {
128     const char *Prefix = *Info->Prefixes;
129     return Prefix ? Prefix : StringRef();
130   }
131
132   /// Get the name of this option with the default prefix.
133   std::string getPrefixedName() const {
134     std::string Ret = getPrefix();
135     Ret += getName();
136     return Ret;
137   }
138
139   unsigned getNumArgs() const { return Info->Param; }
140
141   bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
142
143   RenderStyleKind getRenderStyle() const {
144     if (Info->Flags & RenderJoined)
145       return RenderJoinedStyle;
146     if (Info->Flags & RenderSeparate)
147       return RenderSeparateStyle;
148     switch (getKind()) {
149     case GroupClass:
150     case InputClass:
151     case UnknownClass:
152       return RenderValuesStyle;
153     case JoinedClass:
154     case JoinedAndSeparateClass:
155       return RenderJoinedStyle;
156     case CommaJoinedClass:
157       return RenderCommaJoinedStyle;
158     case FlagClass:
159     case ValuesClass:
160     case SeparateClass:
161     case MultiArgClass:
162     case JoinedOrSeparateClass:
163     case RemainingArgsClass:
164     case RemainingArgsJoinedClass:
165       return RenderSeparateStyle;
166     }
167     llvm_unreachable("Unexpected kind!");
168   }
169
170   /// Test if this option has the flag \a Val.
171   bool hasFlag(unsigned Val) const {
172     return Info->Flags & Val;
173   }
174
175   /// getUnaliasedOption - Return the final option this option
176   /// aliases (itself, if the option has no alias).
177   const Option getUnaliasedOption() const {
178     const Option Alias = getAlias();
179     if (Alias.isValid()) return Alias.getUnaliasedOption();
180     return *this;
181   }
182
183   /// getRenderName - Return the name to use when rendering this
184   /// option.
185   StringRef getRenderName() const {
186     return getUnaliasedOption().getName();
187   }
188
189   /// matches - Predicate for whether this option is part of the
190   /// given option (which may be a group).
191   ///
192   /// Note that matches against options which are an alias should never be
193   /// done -- aliases do not participate in matching and so such a query will
194   /// always be false.
195   bool matches(OptSpecifier ID) const;
196
197   /// accept - Potentially accept the current argument, returning a
198   /// new Arg instance, or 0 if the option does not accept this
199   /// argument (or the argument is missing values).
200   ///
201   /// If the option accepts the current argument, accept() sets
202   /// Index to the position where argument parsing should resume
203   /// (even if the argument is missing values).
204   ///
205   /// \param ArgSize The number of bytes taken up by the matched Option prefix
206   ///                and name. This is used to determine where joined values
207   ///                start.
208   Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
209
210   void print(raw_ostream &O) const;
211   void dump() const;
212 };
213
214 } // end namespace opt
215
216 } // end namespace llvm
217
218 #endif // LLVM_OPTION_OPTION_H