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