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//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_OPTION_OPTION_H
10#define LLVM_OPTION_OPTION_H
11
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>
19
20namespace llvm {
21
22class raw_ostream;
23
24namespace opt {
25
26class Arg;
27class ArgList;
28
29/// ArgStringList - Type used for constructing argv lists for subprocesses.
30using ArgStringList = SmallVector<const char *, 16>;
31
32/// Base flags for all options. Custom flags may be added after.
33enum DriverFlag {
34 HelpHidden = (1 << 0),
35 RenderAsInput = (1 << 1),
36 RenderJoined = (1 << 2),
37 RenderSeparate = (1 << 3)
38};
39
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.
51class Option {
52public:
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
67 };
68
69 enum RenderStyleKind {
70 RenderCommaJoinedStyle,
71 RenderJoinedStyle,
72 RenderSeparateStyle,
73 RenderValuesStyle
74 };
75
76protected:
77 const OptTable::Info *Info;
78 const OptTable *Owner;
79
80public:
81 Option(const OptTable::Info *Info, const OptTable *Owner);
82
83 bool isValid() const {
84 return Info != nullptr;
85 }
86
87 unsigned getID() const {
88 assert(Info && "Must have a valid info!");
89 return Info->ID;
90 }
91
92 OptionClass getKind() const {
93 assert(Info && "Must have a valid info!");
94 return OptionClass(Info->Kind);
95 }
96
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;
101 }
102
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(Opt: Info->GroupID);
107 }
108
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(Opt: Info->AliasID);
113 }
114
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.");
121
122 return Info->AliasArgs;
123 }
124
125 /// Get the default prefix for this option.
126 StringRef getPrefix() const {
127 return Info->Prefixes.empty()
128 ? StringRef()
129 : static_cast<const StringRef &>(Info->Prefixes[0]);
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 /// Get the help text for this option.
140 StringRef getHelpText() const {
141 assert(Info && "Must have a valid info!");
142 return Info->HelpText;
143 }
144
145 /// Get the meta-variable list for this option.
146 StringRef getMetaVar() const {
147 assert(Info && "Must have a valid info!");
148 return Info->MetaVar;
149 }
150
151 unsigned getNumArgs() const { return Info->Param; }
152
153 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
154
155 RenderStyleKind getRenderStyle() const {
156 if (Info->Flags & RenderJoined)
157 return RenderJoinedStyle;
158 if (Info->Flags & RenderSeparate)
159 return RenderSeparateStyle;
160 switch (getKind()) {
161 case GroupClass:
162 case InputClass:
163 case UnknownClass:
164 return RenderValuesStyle;
165 case JoinedClass:
166 case JoinedAndSeparateClass:
167 return RenderJoinedStyle;
168 case CommaJoinedClass:
169 return RenderCommaJoinedStyle;
170 case FlagClass:
171 case ValuesClass:
172 case SeparateClass:
173 case MultiArgClass:
174 case JoinedOrSeparateClass:
175 case RemainingArgsClass:
176 case RemainingArgsJoinedClass:
177 return RenderSeparateStyle;
178 }
179 llvm_unreachable("Unexpected kind!");
180 }
181
182 /// Test if this option has the flag \a Val.
183 bool hasFlag(unsigned Val) const {
184 return Info->Flags & Val;
185 }
186
187 /// getUnaliasedOption - Return the final option this option
188 /// aliases (itself, if the option has no alias).
189 const Option getUnaliasedOption() const {
190 const Option Alias = getAlias();
191 if (Alias.isValid()) return Alias.getUnaliasedOption();
192 return *this;
193 }
194
195 /// getRenderName - Return the name to use when rendering this
196 /// option.
197 StringRef getRenderName() const {
198 return getUnaliasedOption().getName();
199 }
200
201 /// matches - Predicate for whether this option is part of the
202 /// given option (which may be a group).
203 ///
204 /// Note that matches against options which are an alias should never be
205 /// done -- aliases do not participate in matching and so such a query will
206 /// always be false.
207 bool matches(OptSpecifier ID) const;
208
209 /// Potentially accept the current argument, returning a new Arg instance,
210 /// or 0 if the option does not accept this argument (or the argument is
211 /// missing values).
212 ///
213 /// If the option accepts the current argument, accept() sets
214 /// Index to the position where argument parsing should resume
215 /// (even if the argument is missing values).
216 ///
217 /// \p CurArg The argument to be matched. It may be shorter than the
218 /// underlying storage to represent a Joined argument.
219 /// \p GroupedShortOption If true, we are handling the fallback case of
220 /// parsing a prefix of the current argument as a short option.
221 std::unique_ptr<Arg> accept(const ArgList &Args, StringRef CurArg,
222 bool GroupedShortOption, unsigned &Index) const;
223
224private:
225 std::unique_ptr<Arg> acceptInternal(const ArgList &Args, StringRef CurArg,
226 unsigned &Index) const;
227
228public:
229 void print(raw_ostream &O) const;
230 void dump() const;
231};
232
233} // end namespace opt
234
235} // end namespace llvm
236
237#endif // LLVM_OPTION_OPTION_H
238

source code of include/llvm-17/llvm/Option/Option.h