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