blob: c11487e3f9d7c63dfb34b5f0e4769ea0c88a045f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- Option.h - Abstract Driver Options -----------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010097 /// Get the name of this option without any prefix.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010098 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(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(Info->AliasID);
113 }
114
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100115 /// Get the alias arguments as a \0 separated list.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100116 /// 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100125 /// Get the default prefix for this option.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 StringRef getPrefix() const {
127 const char *Prefix = *Info->Prefixes;
128 return Prefix ? Prefix : StringRef();
129 }
130
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100131 /// Get the name of this option with the default prefix.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100132 std::string getPrefixedName() const {
133 std::string Ret = getPrefix();
134 Ret += getName();
135 return Ret;
136 }
137
138 unsigned getNumArgs() const { return Info->Param; }
139
140 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
141
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;
165 }
166 llvm_unreachable("Unexpected kind!");
167 }
168
169 /// Test if this option has the flag \a Val.
170 bool hasFlag(unsigned Val) const {
171 return Info->Flags & Val;
172 }
173
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;
180 }
181
182 /// getRenderName - Return the name to use when rendering this
183 /// option.
184 StringRef getRenderName() const {
185 return getUnaliasedOption().getName();
186 }
187
188 /// matches - Predicate for whether this option is part of the
189 /// given option (which may be a group).
190 ///
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;
195
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).
199 ///
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).
203 ///
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;
208
209 void print(raw_ostream &O) const;
210 void dump() const;
211};
212
213} // end namespace opt
214
215} // end namespace llvm
216
217#endif // LLVM_OPTION_OPTION_H