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