xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Option/Option.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/Compiler.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include <cassert>
19 
20 namespace llvm {
21 
22 class raw_ostream;
23 
24 namespace opt {
25 
26 class Arg;
27 class ArgList;
28 
29 /// ArgStringList - Type used for constructing argv lists for subprocesses.
30 using ArgStringList = SmallVector<const char *, 16>;
31 
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)
38 };
39 
40 enum DriverVisibility {
41   DefaultVis = (1 << 0),
42 };
43 
44 /// Option - Abstract representation for a single form of driver
45 /// argument.
46 ///
47 /// An Option class represents a form of option that the driver
48 /// takes, for example how many arguments the option has and how
49 /// they can be provided. Individual option instances store
50 /// additional information about what group the option is a member
51 /// of (if any), if the option is an alias, and a number of
52 /// flags. At runtime the driver parses the command line into
53 /// concrete Arg instances, each of which corresponds to a
54 /// particular Option instance.
55 class Option {
56 public:
57   enum OptionClass {
58     GroupClass = 0,
59     InputClass,
60     UnknownClass,
61     FlagClass,
62     JoinedClass,
63     ValuesClass,
64     SeparateClass,
65     RemainingArgsClass,
66     RemainingArgsJoinedClass,
67     CommaJoinedClass,
68     MultiArgClass,
69     JoinedOrSeparateClass,
70     JoinedAndSeparateClass
71   };
72 
73   enum RenderStyleKind {
74     RenderCommaJoinedStyle,
75     RenderJoinedStyle,
76     RenderSeparateStyle,
77     RenderValuesStyle
78   };
79 
80 protected:
81   const OptTable::Info *Info;
82   const OptTable *Owner;
83 
84 public:
85   LLVM_ABI Option(const OptTable::Info *Info, const OptTable *Owner);
86 
isValid()87   bool isValid() const {
88     return Info != nullptr;
89   }
90 
getID()91   unsigned getID() const {
92     assert(Info && "Must have a valid info!");
93     return Info->ID;
94   }
95 
getKind()96   OptionClass getKind() const {
97     assert(Info && "Must have a valid info!");
98     return OptionClass(Info->Kind);
99   }
100 
101   /// Get the name of this option without any prefix.
getName()102   StringRef getName() const {
103     assert(Info && "Must have a valid info!");
104     assert(Owner && "Must have a valid owner!");
105     return Owner->getOptionName(Info->ID);
106   }
107 
getGroup()108   const Option getGroup() const {
109     assert(Info && "Must have a valid info!");
110     assert(Owner && "Must have a valid owner!");
111     return Owner->getOption(Info->GroupID);
112   }
113 
getAlias()114   const Option getAlias() const {
115     assert(Info && "Must have a valid info!");
116     assert(Owner && "Must have a valid owner!");
117     return Owner->getOption(Info->AliasID);
118   }
119 
120   /// Get the alias arguments as a \0 separated list.
121   /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
getAliasArgs()122   const char *getAliasArgs() const {
123     assert(Info && "Must have a valid info!");
124     assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
125            "AliasArgs should be either 0 or non-empty.");
126 
127     return Info->AliasArgs;
128   }
129 
130   /// Get the default prefix for this option.
getPrefix()131   StringRef getPrefix() const {
132     assert(Info && "Must have a valid info!");
133     assert(Owner && "Must have a valid owner!");
134     return Owner->getOptionPrefix(Info->ID);
135   }
136 
137   /// Get the name of this option with the default prefix.
getPrefixedName()138   StringRef getPrefixedName() const {
139     assert(Info && "Must have a valid info!");
140     assert(Owner && "Must have a valid owner!");
141     return Owner->getOptionPrefixedName(Info->ID);
142   }
143 
144   /// Get the help text for this option.
getHelpText()145   StringRef getHelpText() const {
146     assert(Info && "Must have a valid info!");
147     return Info->HelpText;
148   }
149 
150   /// Get the meta-variable list for this option.
getMetaVar()151   StringRef getMetaVar() const {
152     assert(Info && "Must have a valid info!");
153     return Info->MetaVar;
154   }
155 
getNumArgs()156   unsigned getNumArgs() const { return Info->Param; }
157 
hasNoOptAsInput()158   bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
159 
getRenderStyle()160   RenderStyleKind getRenderStyle() const {
161     if (Info->Flags & RenderJoined)
162       return RenderJoinedStyle;
163     if (Info->Flags & RenderSeparate)
164       return RenderSeparateStyle;
165     switch (getKind()) {
166     case GroupClass:
167     case InputClass:
168     case UnknownClass:
169       return RenderValuesStyle;
170     case JoinedClass:
171     case JoinedAndSeparateClass:
172       return RenderJoinedStyle;
173     case CommaJoinedClass:
174       return RenderCommaJoinedStyle;
175     case FlagClass:
176     case ValuesClass:
177     case SeparateClass:
178     case MultiArgClass:
179     case JoinedOrSeparateClass:
180     case RemainingArgsClass:
181     case RemainingArgsJoinedClass:
182       return RenderSeparateStyle;
183     }
184     llvm_unreachable("Unexpected kind!");
185   }
186 
187   /// Test if this option has the flag \a Val.
hasFlag(unsigned Val)188   bool hasFlag(unsigned Val) const {
189     return Info->Flags & Val;
190   }
191 
192   /// Test if this option has the visibility flag \a Val.
hasVisibilityFlag(unsigned Val)193   bool hasVisibilityFlag(unsigned Val) const {
194     return Info->Visibility & Val;
195   }
196 
197   /// getUnaliasedOption - Return the final option this option
198   /// aliases (itself, if the option has no alias).
getUnaliasedOption()199   const Option getUnaliasedOption() const {
200     const Option Alias = getAlias();
201     if (Alias.isValid()) return Alias.getUnaliasedOption();
202     return *this;
203   }
204 
205   /// getRenderName - Return the name to use when rendering this
206   /// option.
getRenderName()207   StringRef getRenderName() const {
208     return getUnaliasedOption().getName();
209   }
210 
211   /// matches - Predicate for whether this option is part of the
212   /// given option (which may be a group).
213   ///
214   /// Note that matches against options which are an alias should never be
215   /// done -- aliases do not participate in matching and so such a query will
216   /// always be false.
217   LLVM_ABI bool matches(OptSpecifier ID) const;
218 
219   /// Potentially accept the current argument, returning a new Arg instance,
220   /// or 0 if the option does not accept this argument (or the argument is
221   /// missing values).
222   ///
223   /// If the option accepts the current argument, accept() sets
224   /// Index to the position where argument parsing should resume
225   /// (even if the argument is missing values).
226   ///
227   /// \p CurArg The argument to be matched. It may be shorter than the
228   /// underlying storage to represent a Joined argument.
229   /// \p GroupedShortOption If true, we are handling the fallback case of
230   /// parsing a prefix of the current argument as a short option.
231   LLVM_ABI std::unique_ptr<Arg> accept(const ArgList &Args, StringRef CurArg,
232                                        bool GroupedShortOption,
233                                        unsigned &Index) const;
234 
235 private:
236   std::unique_ptr<Arg> acceptInternal(const ArgList &Args, StringRef CurArg,
237                                       unsigned &Index) const;
238 
239 public:
240   LLVM_ABI void print(raw_ostream &O, bool AddNewLine = true) const;
241   LLVM_ABI void dump() const;
242 };
243 
244 } // end namespace opt
245 
246 } // end namespace llvm
247 
248 #endif // LLVM_OPTION_OPTION_H
249