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
960b57cec5SDimitry Andricclass Option<list<string> prefixes, string name, OptionKind kind> {
970b57cec5SDimitry Andric  string EnumName = ?; // Uses the def name if undefined.
980b57cec5SDimitry Andric  list<string> Prefixes = prefixes;
990b57cec5SDimitry Andric  string Name = name;
1000b57cec5SDimitry Andric  OptionKind Kind = kind;
1010b57cec5SDimitry Andric  // Used by MultiArg option kind.
1020b57cec5SDimitry Andric  int NumArgs = 0;
1030b57cec5SDimitry Andric  string HelpText = ?;
1040b57cec5SDimitry Andric  string MetaVarName = ?;
1050b57cec5SDimitry Andric  string Values = ?;
1060b57cec5SDimitry Andric  code ValuesCode = ?;
1070b57cec5SDimitry Andric  list<OptionFlag> Flags = [];
1085f757f3fSDimitry Andric  list<OptionVisibility> Visibility = [DefaultVis];
1090b57cec5SDimitry Andric  OptionGroup Group = ?;
1100b57cec5SDimitry Andric  Option Alias = ?;
1110b57cec5SDimitry Andric  list<string> AliasArgs = [];
112e8d8bef9SDimitry Andric  code MacroPrefix = "";
1135ffd83dbSDimitry Andric  code KeyPath = ?;
1145ffd83dbSDimitry Andric  code DefaultValue = ?;
115e8d8bef9SDimitry Andric  code ImpliedValue = ?;
116e8d8bef9SDimitry Andric  code ImpliedCheck = "false";
117e8d8bef9SDimitry Andric  code ShouldParse = "true";
118e8d8bef9SDimitry Andric  bit ShouldAlwaysEmit = false;
1195ffd83dbSDimitry Andric  code NormalizerRetTy = ?;
1205ffd83dbSDimitry Andric  code NormalizedValuesScope = "";
1215ffd83dbSDimitry Andric  code Normalizer = "";
1225ffd83dbSDimitry Andric  code Denormalizer = "";
123e8d8bef9SDimitry Andric  code ValueMerger = "mergeForwardValue";
124e8d8bef9SDimitry Andric  code ValueExtractor = "extractForwardValue";
1255ffd83dbSDimitry Andric  list<code> NormalizedValues = ?;
1260b57cec5SDimitry Andric}
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric// Helpers for defining options.
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andricclass Flag<list<string> prefixes, string name>
1310b57cec5SDimitry Andric  : Option<prefixes, name, KIND_FLAG>;
1320b57cec5SDimitry Andricclass Joined<list<string> prefixes, string name>
1330b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED>;
1340b57cec5SDimitry Andricclass Separate<list<string> prefixes, string name>
1350b57cec5SDimitry Andric  : Option<prefixes, name, KIND_SEPARATE>;
1360b57cec5SDimitry Andricclass CommaJoined<list<string> prefixes, string name>
1370b57cec5SDimitry Andric  : Option<prefixes, name, KIND_COMMAJOINED>;
1380b57cec5SDimitry Andricclass MultiArg<list<string> prefixes, string name, int numargs>
1390b57cec5SDimitry Andric  : Option<prefixes, name, KIND_MULTIARG> {
1400b57cec5SDimitry Andric  int NumArgs = numargs;
1410b57cec5SDimitry Andric}
1420b57cec5SDimitry Andricclass JoinedOrSeparate<list<string> prefixes, string name>
1430b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>;
1440b57cec5SDimitry Andricclass JoinedAndSeparate<list<string> prefixes, string name>
1450b57cec5SDimitry Andric  : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>;
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric// Mix-ins for adding optional attributes.
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andricclass Alias<Option alias> { Option Alias = alias; }
1500b57cec5SDimitry Andricclass AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
1510b57cec5SDimitry Andricclass EnumName<string name> { string EnumName = name; }
1520b57cec5SDimitry Andricclass Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
1535f757f3fSDimitry Andricclass Visibility<list<OptionVisibility> visibility> {
1545f757f3fSDimitry Andric  list<OptionVisibility> Visibility = visibility;
1555f757f3fSDimitry Andric}
1560b57cec5SDimitry Andricclass Group<OptionGroup group> { OptionGroup Group = group; }
1570b57cec5SDimitry Andricclass HelpText<string text> { string HelpText = text; }
1580b57cec5SDimitry Andricclass MetaVarName<string name> { string MetaVarName = name; }
1590b57cec5SDimitry Andricclass Values<string value> { string Values = value; }
1600b57cec5SDimitry Andricclass ValuesCode<code valuecode> { code ValuesCode = valuecode; }
1610b57cec5SDimitry Andric
162fe6060f1SDimitry Andric// Helpers for defining marshalling information (typically used in Clang's -cc1
163fe6060f1SDimitry Andric// frontend).
1645ffd83dbSDimitry Andric
165fe6060f1SDimitry Andric// The key path to the mapped field and the macro prefix for the resulting
166fe6060f1SDimitry Andric// definition database.
167e8d8bef9SDimitry Andricclass KeyPathAndMacro<string key_path_prefix, string key_path_base,
168e8d8bef9SDimitry Andric                      string macro_prefix = ""> {
169e8d8bef9SDimitry Andric  code KeyPath = !strconcat(key_path_prefix, key_path_base);
170e8d8bef9SDimitry Andric  code MacroPrefix = macro_prefix;
1715ffd83dbSDimitry Andric}
1725ffd83dbSDimitry Andric
173fe6060f1SDimitry Andric// Mixin that implies the specified value for the current option when any of the
174fe6060f1SDimitry Andric// given key paths evaluates to true.
175e8d8bef9SDimitry Andricclass ImpliedByAnyOf<list<string> key_paths, code value = "true"> {
176e8d8bef9SDimitry Andric  code ImpliedCheck = !foldl("false", key_paths, accumulator, key_path,
177e8d8bef9SDimitry Andric                             !strconcat(accumulator, " || ", key_path));
178e8d8bef9SDimitry Andric  code ImpliedValue = value;
179e8d8bef9SDimitry Andric}
180e8d8bef9SDimitry Andric
181fe6060f1SDimitry Andric// Parent class for marshalled options (typically used in Clang's -cc1 frontend).
182e8d8bef9SDimitry Andricclass MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> {
183e8d8bef9SDimitry Andric  code KeyPath = kpm.KeyPath;
184e8d8bef9SDimitry Andric  code MacroPrefix = kpm.MacroPrefix;
185e8d8bef9SDimitry Andric  code DefaultValue = defaultvalue;
186e8d8bef9SDimitry Andric}
187e8d8bef9SDimitry Andric
188fe6060f1SDimitry Andric// Marshalled option accepting a string argument.
189e8d8bef9SDimitry Andricclass MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()">
190e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
191e8d8bef9SDimitry Andric  code Normalizer = "normalizeString";
192e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeString";
193e8d8bef9SDimitry Andric}
194e8d8bef9SDimitry Andric
195fe6060f1SDimitry Andric// Marshalled option accepting an integer argument.
196fe6060f1SDimitry Andricclass MarshallingInfoInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
197e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
198e8d8bef9SDimitry Andric  code Normalizer = "normalizeStringIntegral<"#type#">";
199fe6060f1SDimitry Andric  code Denormalizer = "denormalizeString<"#type#">";
200e8d8bef9SDimitry Andric}
201e8d8bef9SDimitry Andric
202fe6060f1SDimitry Andric// Marshalled option accepting vector of strings.
203e8d8bef9SDimitry Andricclass MarshallingInfoStringVector<KeyPathAndMacro kpm>
204e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, "std::vector<std::string>({})"> {
205e8d8bef9SDimitry Andric  code Normalizer = "normalizeStringVector";
206e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeStringVector";
207e8d8bef9SDimitry Andric}
208e8d8bef9SDimitry Andric
209fe6060f1SDimitry Andric// Marshalled option - single positive flag.
210e8d8bef9SDimitry Andricclass MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false">
211e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
212e8d8bef9SDimitry Andric  code Normalizer = "normalizeSimpleFlag";
213e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeSimpleFlag";
214e8d8bef9SDimitry Andric}
215e8d8bef9SDimitry Andric
216fe6060f1SDimitry Andric// Marshalled option - single negative flag.
217e8d8bef9SDimitry Andricclass MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true">
218e8d8bef9SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
219e8d8bef9SDimitry Andric  code Normalizer = "normalizeSimpleNegativeFlag";
220e8d8bef9SDimitry Andric  code Denormalizer = "denormalizeSimpleFlag";
221e8d8bef9SDimitry Andric}
222e8d8bef9SDimitry Andric
223fe6060f1SDimitry Andric// Marshalled option - single flag contributing to a bitfield.
224e8d8bef9SDimitry Andricclass MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value>
225e8d8bef9SDimitry Andric  : MarshallingInfoFlag<kpm, "0u"> {
226e8d8bef9SDimitry Andric  code Normalizer = "makeFlagToValueNormalizer("#value#")";
227e8d8bef9SDimitry Andric  code ValueMerger = "mergeMaskValue";
228e8d8bef9SDimitry Andric  code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
229e8d8bef9SDimitry Andric}
230e8d8bef9SDimitry Andric
231fe6060f1SDimitry Andric// Implementation detail of BoolOption.
232349cc55cSDimitry Andricclass MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value,
233e8d8bef9SDimitry Andric                                 code other_value, code other_name>
234e8d8bef9SDimitry Andric  : MarshallingInfoFlag<kpm, defaultvalue> {
235e8d8bef9SDimitry Andric  code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")";
236e8d8bef9SDimitry Andric  code Denormalizer = "makeBooleanOptionDenormalizer("#value#")";
2375ffd83dbSDimitry Andric}
2385ffd83dbSDimitry Andric
239fe6060f1SDimitry Andric// Marshalled option accepting any of the specified enum values.
240fe6060f1SDimitry Andric// Typically used with `Values`, `NormalizedValues` and `NormalizedValuesScope`.
241fe6060f1SDimitry Andricclass MarshallingInfoEnum<KeyPathAndMacro kpm, code defaultvalue>
242fe6060f1SDimitry Andric  : MarshallingInfo<kpm, defaultvalue> {
243fe6060f1SDimitry Andric  code Normalizer = "normalizeSimpleEnum";
244fe6060f1SDimitry Andric  code Denormalizer = "denormalizeSimpleEnum";
245fe6060f1SDimitry Andric}
246fe6060f1SDimitry Andric
2475ffd83dbSDimitry Andric// Mixins for additional marshalling attributes.
2485ffd83dbSDimitry Andric
249e8d8bef9SDimitry Andricclass ShouldParseIf<code condition> { code ShouldParse = condition; }
250e8d8bef9SDimitry Andricclass AlwaysEmit { bit ShouldAlwaysEmit = true; }
2515ffd83dbSDimitry Andricclass Normalizer<code normalizer> { code Normalizer = normalizer; }
2525ffd83dbSDimitry Andricclass Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
2535ffd83dbSDimitry Andricclass NormalizedValuesScope<code scope> { code NormalizedValuesScope = scope; }
2545ffd83dbSDimitry Andricclass NormalizedValues<list<code> definitions> { list<code> NormalizedValues = definitions; }
255e8d8bef9SDimitry Andricclass ValueMerger<code merger> { code ValueMerger = merger; }
256e8d8bef9SDimitry Andricclass ValueExtractor<code extractor> { code ValueExtractor = extractor; }
2575ffd83dbSDimitry Andric
2580b57cec5SDimitry Andric// Predefined options.
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric// FIXME: Have generator validate that these appear in correct position (and
2610b57cec5SDimitry Andric// aren't duplicated).
2620b57cec5SDimitry Andricdef INPUT : Option<[], "<input>", KIND_INPUT>;
2630b57cec5SDimitry Andricdef UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>;
26406c3fb27SDimitry Andric
26506c3fb27SDimitry Andric#endif // LLVM_OPTION_OPTPARSER_TD
266