xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Option/OptParser.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric//  This file defines the common interfaces used by the option parsing TableGen
100b57cec5SDimitry Andric//  backend.
110b57cec5SDimitry Andric//
120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
1406c3fb27SDimitry Andric#ifndef LLVM_OPTION_OPTPARSER_TD
1506c3fb27SDimitry Andric#define LLVM_OPTION_OPTPARSER_TD
1606c3fb27SDimitry Andric
170b57cec5SDimitry Andric// Define the kinds of options.
180b57cec5SDimitry Andric
19e8d8bef9SDimitry Andricclass OptionKind<string name, int precedence = 0, bit sentinel = false> {
200b57cec5SDimitry Andric  string Name = name;
210b57cec5SDimitry Andric  // The kind precedence, kinds with lower precedence are matched first.
220b57cec5SDimitry Andric  int Precedence = precedence;
230b57cec5SDimitry Andric  // Indicate a sentinel option.
240b57cec5SDimitry Andric  bit Sentinel = sentinel;
250b57cec5SDimitry Andric}
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric// An option group.
280b57cec5SDimitry Andricdef KIND_GROUP : OptionKind<"Group">;
290b57cec5SDimitry Andric// The input option kind.
30e8d8bef9SDimitry Andricdef KIND_INPUT : OptionKind<"Input", 1, true>;
310b57cec5SDimitry Andric// The unknown option kind.
32e8d8bef9SDimitry Andricdef KIND_UNKNOWN : OptionKind<"Unknown", 2, true>;
330b57cec5SDimitry Andric// A flag with no values.
340b57cec5SDimitry Andricdef KIND_FLAG : OptionKind<"Flag">;
350b57cec5SDimitry Andric// An option which prefixes its (single) value.
360b57cec5SDimitry Andricdef KIND_JOINED : OptionKind<"Joined", 1>;
370b57cec5SDimitry Andric// An option which is followed by its value.
380b57cec5SDimitry Andricdef KIND_SEPARATE : OptionKind<"Separate">;
390b57cec5SDimitry Andric// An option followed by its values, which are separated by commas.
400b57cec5SDimitry Andricdef KIND_COMMAJOINED : OptionKind<"CommaJoined">;
410b57cec5SDimitry Andric// An option which is which takes multiple (separate) arguments.
420b57cec5SDimitry Andricdef KIND_MULTIARG : OptionKind<"MultiArg">;
430b57cec5SDimitry Andric// An option which is either joined to its (non-empty) value, or followed by its
440b57cec5SDimitry Andric// value.
450b57cec5SDimitry Andricdef KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
460b57cec5SDimitry Andric// An option which is both joined to its (first) value, and followed by its
470b57cec5SDimitry Andric// (second) value.
480b57cec5SDimitry Andricdef KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
490b57cec5SDimitry Andric// An option which consumes all remaining arguments if there are any.
500b57cec5SDimitry Andricdef KIND_REMAINING_ARGS : OptionKind<"RemainingArgs">;
510b57cec5SDimitry Andric// An option which consumes an optional joined argument and any other remaining
520b57cec5SDimitry Andric// arguments.
530b57cec5SDimitry Andricdef KIND_REMAINING_ARGS_JOINED : OptionKind<"RemainingArgsJoined">;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric// Define the option flags.
560b57cec5SDimitry Andric
570b57cec5SDimitry Andricclass OptionFlag {}
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric// HelpHidden - The option should not be displayed in --help, even if it has
600b57cec5SDimitry Andric// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp
610b57cec5SDimitry Andric// arguments to implement hidden help groups.
620b57cec5SDimitry Andricdef HelpHidden : OptionFlag;
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric// RenderAsInput - The option should not render the name when rendered as an
650b57cec5SDimitry Andric// input (i.e., the option is rendered as values).
660b57cec5SDimitry Andricdef RenderAsInput : OptionFlag;
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric// RenderJoined - The option should be rendered joined, even if separate (only
690b57cec5SDimitry Andric// sensible on single value separate options).
700b57cec5SDimitry Andricdef RenderJoined : OptionFlag;
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric// RenderSeparate - The option should be rendered separately, even if joined
730b57cec5SDimitry Andric// (only sensible on joined options).
740b57cec5SDimitry Andricdef RenderSeparate : OptionFlag;
750b57cec5SDimitry Andric
765f757f3fSDimitry Andric// Define Visibility categories
775f757f3fSDimitry Andric
785f757f3fSDimitry Andricclass OptionVisibility {}
795f757f3fSDimitry Andric
805f757f3fSDimitry Andric// Explicit specifier for default visibility
815f757f3fSDimitry Andricdef DefaultVis : OptionVisibility;
825f757f3fSDimitry Andric
830b57cec5SDimitry Andric// Define the option group class.
840b57cec5SDimitry Andric
850b57cec5SDimitry Andricclass OptionGroup<string name> {
860b57cec5SDimitry Andric  string EnumName = ?; // Uses the def name if undefined.
870b57cec5SDimitry Andric  string Name = name;
880b57cec5SDimitry Andric  string HelpText = ?;
890b57cec5SDimitry Andric  OptionGroup Group = ?;
900b57cec5SDimitry Andric  list<OptionFlag> Flags = [];
915f757f3fSDimitry Andric  list<OptionVisibility> Visibility = [];
920b57cec5SDimitry Andric}
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric// Define the option class.
950b57cec5SDimitry Andric
96*0fca6ea1SDimitry Andricclass HelpTextVariant<list<OptionVisibility> visibilities, string text> {
97*0fca6ea1SDimitry Andric  list<OptionVisibility> Visibilities = visibilities;
98*0fca6ea1SDimitry Andric  string Text = text;
99*0fca6ea1SDimitry Andric}
100*0fca6ea1SDimitry Andric
1010b57cec5SDimitry Andricclass Option<list<string> prefixes, string name, OptionKind kind> {
1020b57cec5SDimitry Andric  string EnumName = ?; // Uses the def name if undefined.
1030b57cec5SDimitry Andric  list<string> Prefixes = prefixes;
1040b57cec5SDimitry Andric  string Name = name;
1050b57cec5SDimitry Andric  OptionKind Kind = kind;
1060b57cec5SDimitry Andric  // Used by MultiArg option kind.
1070b57cec5SDimitry Andric  int NumArgs = 0;
1080b57cec5SDimitry Andric  string HelpText = ?;
109*0fca6ea1SDimitry Andric  list<HelpTextVariant> HelpTextsForVariants = [];
1100b57cec5SDimitry Andric  string MetaVarName = ?;
1110b57cec5SDimitry Andric  string Values = ?;
1120b57cec5SDimitry Andric  code ValuesCode = ?;
1130b57cec5SDimitry Andric  list<OptionFlag> Flags = [];
1145f757f3fSDimitry Andric  list<OptionVisibility> Visibility = [DefaultVis];
1150b57cec5SDimitry Andric  OptionGroup Group = ?;
1160b57cec5SDimitry Andric  Option Alias = ?;
1170b57cec5SDimitry Andric  list<string> AliasArgs = [];
118e8d8bef9SDimitry Andric  code MacroPrefix = "";
1195ffd83dbSDimitry Andric  code KeyPath = ?;
1205ffd83dbSDimitry Andric  code DefaultValue = ?;
121e8d8bef9SDimitry Andric  code ImpliedValue = ?;
122e8d8bef9SDimitry Andric  code ImpliedCheck = "false";
123e8d8bef9SDimitry Andric  code ShouldParse = "true";
124e8d8bef9SDimitry Andric  bit ShouldAlwaysEmit = false;
1255ffd83dbSDimitry Andric  code NormalizerRetTy = ?;
1265ffd83dbSDimitry Andric  code NormalizedValuesScope = "";
1275ffd83dbSDimitry Andric  code Normalizer = "";
1285ffd83dbSDimitry Andric  code Denormalizer = "";
129e8d8bef9SDimitry Andric  code ValueMerger = "mergeForwardValue";
130e8d8bef9SDimitry Andric  code ValueExtractor = "extractForwardValue";
1315ffd83dbSDimitry Andric  list<code> NormalizedValues = ?;
1320b57cec5SDimitry Andric}
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric// Helpers for defining options.
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andricclass Flag<list<string> prefixes, string name>
1370b57cec5SDimitry Andric  : Option<prefixes, name, KIND_FLAG>;
1380b57cec5SDimitry Andricclass Joined<list<string> prefixes, string name>
1390b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED>;
1400b57cec5SDimitry Andricclass Separate<list<string> prefixes, string name>
1410b57cec5SDimitry Andric  : Option<prefixes, name, KIND_SEPARATE>;
1420b57cec5SDimitry Andricclass CommaJoined<list<string> prefixes, string name>
1430b57cec5SDimitry Andric  : Option<prefixes, name, KIND_COMMAJOINED>;
1440b57cec5SDimitry Andricclass MultiArg<list<string> prefixes, string name, int numargs>
1450b57cec5SDimitry Andric  : Option<prefixes, name, KIND_MULTIARG> {
1460b57cec5SDimitry Andric  int NumArgs = numargs;
1470b57cec5SDimitry Andric}
1480b57cec5SDimitry Andricclass JoinedOrSeparate<list<string> prefixes, string name>
1490b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>;
1500b57cec5SDimitry Andricclass JoinedAndSeparate<list<string> prefixes, string name>
1510b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>;
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric// Mix-ins for adding optional attributes.
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andricclass Alias<Option alias> { Option Alias = alias; }
1560b57cec5SDimitry Andricclass AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
1570b57cec5SDimitry Andricclass EnumName<string name> { string EnumName = name; }
1580b57cec5SDimitry Andricclass Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
1595f757f3fSDimitry Andricclass Visibility<list<OptionVisibility> visibility> {
1605f757f3fSDimitry Andric  list<OptionVisibility> Visibility = visibility;
1615f757f3fSDimitry Andric}
1620b57cec5SDimitry Andricclass Group<OptionGroup group> { OptionGroup Group = group; }
1630b57cec5SDimitry Andricclass HelpText<string text> { string HelpText = text; }
164*0fca6ea1SDimitry Andricclass HelpTextForVariants<list<OptionVisibility> Visibilities, string text> {
165*0fca6ea1SDimitry Andric  list<HelpTextVariant> HelpTextsForVariants = [
166*0fca6ea1SDimitry Andric    HelpTextVariant<Visibilities, text>
167*0fca6ea1SDimitry Andric  ];
168*0fca6ea1SDimitry Andric}
169*0fca6ea1SDimitry Andric
1700b57cec5SDimitry Andricclass MetaVarName<string name> { string MetaVarName = name; }
1710b57cec5SDimitry Andricclass Values<string value> { string Values = value; }
1720b57cec5SDimitry Andricclass ValuesCode<code valuecode> { code ValuesCode = valuecode; }
1730b57cec5SDimitry Andric
174fe6060f1SDimitry Andric// Helpers for defining marshalling information (typically used in Clang's -cc1
175fe6060f1SDimitry Andric// frontend).
1765ffd83dbSDimitry Andric
177fe6060f1SDimitry Andric// The key path to the mapped field and the macro prefix for the resulting
178fe6060f1SDimitry Andric// definition database.
179e8d8bef9SDimitry Andricclass KeyPathAndMacro<string key_path_prefix, string key_path_base,
180e8d8bef9SDimitry Andric                      string macro_prefix = ""> {
181e8d8bef9SDimitry Andric  code KeyPath = !strconcat(key_path_prefix, key_path_base);
182e8d8bef9SDimitry Andric  code MacroPrefix = macro_prefix;
1835ffd83dbSDimitry Andric}
1845ffd83dbSDimitry Andric
185fe6060f1SDimitry Andric// Mixin that implies the specified value for the current option when any of the
186fe6060f1SDimitry Andric// given key paths evaluates to true.
187e8d8bef9SDimitry Andricclass ImpliedByAnyOf<list<string> key_paths, code value = "true"> {
188e8d8bef9SDimitry Andric  code ImpliedCheck = !foldl("false", key_paths, accumulator, key_path,
189e8d8bef9SDimitry Andric                             !strconcat(accumulator, " || ", key_path));
190e8d8bef9SDimitry Andric  code ImpliedValue = value;
191e8d8bef9SDimitry Andric}
192e8d8bef9SDimitry Andric
193fe6060f1SDimitry Andric// Parent class for marshalled options (typically used in Clang's -cc1 frontend).
194e8d8bef9SDimitry Andricclass MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> {
195e8d8bef9SDimitry Andric  code KeyPath = kpm.KeyPath;
196e8d8bef9SDimitry Andric  code MacroPrefix = kpm.MacroPrefix;
197e8d8bef9SDimitry Andric  code DefaultValue = defaultvalue;
198e8d8bef9SDimitry Andric}
199e8d8bef9SDimitry Andric
200fe6060f1SDimitry Andric// Marshalled option accepting a string argument.
201e8d8bef9SDimitry Andricclass MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()">
202e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
203e8d8bef9SDimitry Andric  code Normalizer = "normalizeString";
204e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeString";
205e8d8bef9SDimitry Andric}
206e8d8bef9SDimitry Andric
207fe6060f1SDimitry Andric// Marshalled option accepting an integer argument.
208fe6060f1SDimitry Andricclass MarshallingInfoInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
209e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
210e8d8bef9SDimitry Andric  code Normalizer = "normalizeStringIntegral<"#type#">";
211fe6060f1SDimitry Andric  code Denormalizer = "denormalizeString<"#type#">";
212e8d8bef9SDimitry Andric}
213e8d8bef9SDimitry Andric
214fe6060f1SDimitry Andric// Marshalled option accepting vector of strings.
215e8d8bef9SDimitry Andricclass MarshallingInfoStringVector<KeyPathAndMacro kpm>
216e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, "std::vector<std::string>({})"> {
217e8d8bef9SDimitry Andric  code Normalizer = "normalizeStringVector";
218e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeStringVector";
219e8d8bef9SDimitry Andric}
220e8d8bef9SDimitry Andric
221fe6060f1SDimitry Andric// Marshalled option - single positive flag.
222e8d8bef9SDimitry Andricclass MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false">
223e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
224e8d8bef9SDimitry Andric  code Normalizer = "normalizeSimpleFlag";
225e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeSimpleFlag";
226e8d8bef9SDimitry Andric}
227e8d8bef9SDimitry Andric
228fe6060f1SDimitry Andric// Marshalled option - single negative flag.
229e8d8bef9SDimitry Andricclass MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true">
230e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
231e8d8bef9SDimitry Andric  code Normalizer = "normalizeSimpleNegativeFlag";
232e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeSimpleFlag";
233e8d8bef9SDimitry Andric}
234e8d8bef9SDimitry Andric
235fe6060f1SDimitry Andric// Marshalled option - single flag contributing to a bitfield.
236e8d8bef9SDimitry Andricclass MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value>
237e8d8bef9SDimitry Andric  : MarshallingInfoFlag<kpm, "0u"> {
238e8d8bef9SDimitry Andric  code Normalizer = "makeFlagToValueNormalizer("#value#")";
239e8d8bef9SDimitry Andric  code ValueMerger = "mergeMaskValue";
240e8d8bef9SDimitry Andric  code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
241e8d8bef9SDimitry Andric}
242e8d8bef9SDimitry Andric
243fe6060f1SDimitry Andric// Implementation detail of BoolOption.
244349cc55cSDimitry Andricclass MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value,
245e8d8bef9SDimitry Andric                                 code other_value, code other_name>
246e8d8bef9SDimitry Andric  : MarshallingInfoFlag<kpm, defaultvalue> {
247e8d8bef9SDimitry Andric  code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")";
248e8d8bef9SDimitry Andric  code Denormalizer = "makeBooleanOptionDenormalizer("#value#")";
2495ffd83dbSDimitry Andric}
2505ffd83dbSDimitry Andric
251fe6060f1SDimitry Andric// Marshalled option accepting any of the specified enum values.
252fe6060f1SDimitry Andric// Typically used with `Values`, `NormalizedValues` and `NormalizedValuesScope`.
253fe6060f1SDimitry Andricclass MarshallingInfoEnum<KeyPathAndMacro kpm, code defaultvalue>
254fe6060f1SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
255fe6060f1SDimitry Andric  code Normalizer = "normalizeSimpleEnum";
256fe6060f1SDimitry Andric  code Denormalizer = "denormalizeSimpleEnum";
257fe6060f1SDimitry Andric}
258fe6060f1SDimitry Andric
2595ffd83dbSDimitry Andric// Mixins for additional marshalling attributes.
2605ffd83dbSDimitry Andric
261e8d8bef9SDimitry Andricclass ShouldParseIf<code condition> { code ShouldParse = condition; }
262e8d8bef9SDimitry Andricclass AlwaysEmit { bit ShouldAlwaysEmit = true; }
2635ffd83dbSDimitry Andricclass Normalizer<code normalizer> { code Normalizer = normalizer; }
2645ffd83dbSDimitry Andricclass Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
2655ffd83dbSDimitry Andricclass NormalizedValuesScope<code scope> { code NormalizedValuesScope = scope; }
2665ffd83dbSDimitry Andricclass NormalizedValues<list<code> definitions> { list<code> NormalizedValues = definitions; }
267e8d8bef9SDimitry Andricclass ValueMerger<code merger> { code ValueMerger = merger; }
268e8d8bef9SDimitry Andricclass ValueExtractor<code extractor> { code ValueExtractor = extractor; }
2695ffd83dbSDimitry Andric
2700b57cec5SDimitry Andric// Predefined options.
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric// FIXME: Have generator validate that these appear in correct position (and
2730b57cec5SDimitry Andric// aren't duplicated).
2740b57cec5SDimitry Andricdef INPUT : Option<[], "<input>", KIND_INPUT>;
2750b57cec5SDimitry Andricdef UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>;
27606c3fb27SDimitry Andric
27706c3fb27SDimitry Andric#endif // LLVM_OPTION_OPTPARSER_TD
278