Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===--- OptParser.td - Common Option Parsing Interfaces ------------------===// | 
| 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 | // This file defines the common interfaces used by the option parsing TableGen | ||
| 10 | // backend. | ||
| 11 | // | ||
| 12 | //===----------------------------------------------------------------------===// | ||
| 13 | |||
| 14 | // Define the kinds of options. | ||
| 15 | |||
| 16 | class OptionKind<string name, int precedence = 0, bit sentinel = false> { | ||
| 17 | string Name = name; | ||
| 18 | // The kind precedence, kinds with lower precedence are matched first. | ||
| 19 | int Precedence = precedence; | ||
| 20 | // Indicate a sentinel option. | ||
| 21 | bit Sentinel = sentinel; | ||
| 22 | } | ||
| 23 | |||
| 24 | // An option group. | ||
| 25 | def KIND_GROUP : OptionKind<"Group">; | ||
| 26 | // The input option kind. | ||
| 27 | def KIND_INPUT : OptionKind<"Input", 1, true>; | ||
| 28 | // The unknown option kind. | ||
| 29 | def KIND_UNKNOWN : OptionKind<"Unknown", 2, true>; | ||
| 30 | // A flag with no values. | ||
| 31 | def KIND_FLAG : OptionKind<"Flag">; | ||
| 32 | // An option which prefixes its (single) value. | ||
| 33 | def KIND_JOINED : OptionKind<"Joined", 1>; | ||
| 34 | // An option which is followed by its value. | ||
| 35 | def KIND_SEPARATE : OptionKind<"Separate">; | ||
| 36 | // An option followed by its values, which are separated by commas. | ||
| 37 | def KIND_COMMAJOINED : OptionKind<"CommaJoined">; | ||
| 38 | // An option which is which takes multiple (separate) arguments. | ||
| 39 | def KIND_MULTIARG : OptionKind<"MultiArg">; | ||
| 40 | // An option which is either joined to its (non-empty) value, or followed by its | ||
| 41 | // value. | ||
| 42 | def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">; | ||
| 43 | // An option which is both joined to its (first) value, and followed by its | ||
| 44 | // (second) value. | ||
| 45 | def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">; | ||
| 46 | // An option which consumes all remaining arguments if there are any. | ||
| 47 | def KIND_REMAINING_ARGS : OptionKind<"RemainingArgs">; | ||
| 48 | // An option which consumes an optional joined argument and any other remaining | ||
| 49 | // arguments. | ||
| 50 | def KIND_REMAINING_ARGS_JOINED : OptionKind<"RemainingArgsJoined">; | ||
| 51 | |||
| 52 | // Define the option flags. | ||
| 53 | |||
| 54 | class OptionFlag {} | ||
| 55 | |||
| 56 | // HelpHidden - The option should not be displayed in --help, even if it has | ||
| 57 | // help text. Clients *can* use this in conjunction with the OptTable::PrintHelp | ||
| 58 | // arguments to implement hidden help groups. | ||
| 59 | def HelpHidden : OptionFlag; | ||
| 60 | |||
| 61 | // RenderAsInput - The option should not render the name when rendered as an | ||
| 62 | // input (i.e., the option is rendered as values). | ||
| 63 | def RenderAsInput : OptionFlag; | ||
| 64 | |||
| 65 | // RenderJoined - The option should be rendered joined, even if separate (only | ||
| 66 | // sensible on single value separate options). | ||
| 67 | def RenderJoined : OptionFlag; | ||
| 68 | |||
| 69 | // RenderSeparate - The option should be rendered separately, even if joined | ||
| 70 | // (only sensible on joined options). | ||
| 71 | def RenderSeparate : OptionFlag; | ||
| 72 | |||
| 73 | // Define the option group class. | ||
| 74 | |||
| 75 | class OptionGroup<string name> { | ||
| 76 | string EnumName = ?; // Uses the def name if undefined. | ||
| 77 | string Name = name; | ||
| 78 | string HelpText = ?; | ||
| 79 | OptionGroup Group = ?; | ||
| 80 | list<OptionFlag> Flags = []; | ||
| 81 | } | ||
| 82 | |||
| 83 | // Define the option class. | ||
| 84 | |||
| 85 | class Option<list<string> prefixes, string name, OptionKind kind> { | ||
| 86 | string EnumName = ?; // Uses the def name if undefined. | ||
| 87 | list<string> Prefixes = prefixes; | ||
| 88 | string Name = name; | ||
| 89 | OptionKind Kind = kind; | ||
| 90 | // Used by MultiArg option kind. | ||
| 91 | int NumArgs = 0; | ||
| 92 | string HelpText = ?; | ||
| 93 | string MetaVarName = ?; | ||
| 94 | string Values = ?; | ||
| 95 | code ValuesCode = ?; | ||
| 96 | list<OptionFlag> Flags = []; | ||
| 97 | OptionGroup Group = ?; | ||
| 98 | Option Alias = ?; | ||
| 99 | list<string> AliasArgs = []; | ||
| 100 | code MacroPrefix = ""; | ||
| 101 | code KeyPath = ?; | ||
| 102 | code DefaultValue = ?; | ||
| 103 | code ImpliedValue = ?; | ||
| 104 | code ImpliedCheck = "false"; | ||
| 105 | code ShouldParse = "true"; | ||
| 106 | bit ShouldAlwaysEmit = false; | ||
| 107 | code NormalizerRetTy = ?; | ||
| 108 | code NormalizedValuesScope = ""; | ||
| 109 | code Normalizer = ""; | ||
| 110 | code Denormalizer = ""; | ||
| 111 | code ValueMerger = "mergeForwardValue"; | ||
| 112 | code ValueExtractor = "extractForwardValue"; | ||
| 113 | list<code> NormalizedValues = ?; | ||
| 114 | } | ||
| 115 | |||
| 116 | // Helpers for defining options. | ||
| 117 | |||
| 118 | class Flag<list<string> prefixes, string name> | ||
| 119 | : Option<prefixes, name, KIND_FLAG>; | ||
| 120 | class Joined<list<string> prefixes, string name> | ||
| 121 | : Option<prefixes, name, KIND_JOINED>; | ||
| 122 | class Separate<list<string> prefixes, string name> | ||
| 123 | : Option<prefixes, name, KIND_SEPARATE>; | ||
| 124 | class CommaJoined<list<string> prefixes, string name> | ||
| 125 | : Option<prefixes, name, KIND_COMMAJOINED>; | ||
| 126 | class MultiArg<list<string> prefixes, string name, int numargs> | ||
| 127 |   : Option<prefixes, name, KIND_MULTIARG> { | ||
| 128 | int NumArgs = numargs; | ||
| 129 | } | ||
| 130 | class JoinedOrSeparate<list<string> prefixes, string name> | ||
| 131 | : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>; | ||
| 132 | class JoinedAndSeparate<list<string> prefixes, string name> | ||
| 133 | : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>; | ||
| 134 | |||
| 135 | // Mix-ins for adding optional attributes. | ||
| 136 | |||
| 137 | class Alias<Option alias> { Option Alias = alias; } | ||
| 138 | class AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; } | ||
| 139 | class EnumName<string name> { string EnumName = name; } | ||
| 140 | class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } | ||
| 141 | class Group<OptionGroup group> { OptionGroup Group = group; } | ||
| 142 | class HelpText<string text> { string HelpText = text; } | ||
| 143 | class MetaVarName<string name> { string MetaVarName = name; } | ||
| 144 | class Values<string value> { string Values = value; } | ||
| 145 | class ValuesCode<code valuecode> { code ValuesCode = valuecode; } | ||
| 146 | |||
| 147 | // Helpers for defining marshalling information (typically used in Clang's -cc1 | ||
| 148 | // frontend). | ||
| 149 | |||
| 150 | // The key path to the mapped field and the macro prefix for the resulting | ||
| 151 | // definition database. | ||
| 152 | class KeyPathAndMacro<string key_path_prefix, string key_path_base, | ||
| 153 |                       string macro_prefix = ""> { | ||
| 154 | code KeyPath = !strconcat(key_path_prefix, key_path_base); | ||
| 155 | code MacroPrefix = macro_prefix; | ||
| 156 | } | ||
| 157 | |||
| 158 | // Mixin that implies the specified value for the current option when any of the | ||
| 159 | // given key paths evaluates to true. | ||
| 160 | class ImpliedByAnyOf<list<string> key_paths, code value = "true"> { | ||
| 161 |   code ImpliedCheck = !foldl("false", key_paths, accumulator, key_path, | ||
| 162 | !strconcat(accumulator, " || ", key_path)); | ||
| 163 | code ImpliedValue = value; | ||
| 164 | } | ||
| 165 | |||
| 166 | // Parent class for marshalled options (typically used in Clang's -cc1 frontend). | ||
| 167 | class MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> { | ||
| 168 | code KeyPath = kpm.KeyPath; | ||
| 169 | code MacroPrefix = kpm.MacroPrefix; | ||
| 170 | code DefaultValue = defaultvalue; | ||
| 171 | } | ||
| 172 | |||
| 173 | // Marshalled option accepting a string argument. | ||
| 174 | class MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()"> | ||
| 175 |   : MarshallingInfo<kpm, defaultvalue> { | ||
| 176 | code Normalizer = "normalizeString"; | ||
| 177 | code Denormalizer = "denormalizeString"; | ||
| 178 | } | ||
| 179 | |||
| 180 | // Marshalled option accepting an integer argument. | ||
| 181 | class MarshallingInfoInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned"> | ||
| 182 |   : MarshallingInfo<kpm, defaultvalue> { | ||
| 183 | code Normalizer = "normalizeStringIntegral<"#type#">"; | ||
| 184 | code Denormalizer = "denormalizeString<"#type#">"; | ||
| 185 | } | ||
| 186 | |||
| 187 | // Marshalled option accepting vector of strings. | ||
| 188 | class MarshallingInfoStringVector<KeyPathAndMacro kpm> | ||
| 189 |   : MarshallingInfo<kpm, "std::vector<std::string>({})"> { | ||
| 190 | code Normalizer = "normalizeStringVector"; | ||
| 191 | code Denormalizer = "denormalizeStringVector"; | ||
| 192 | } | ||
| 193 | |||
| 194 | // Marshalled option - single positive flag. | ||
| 195 | class MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false"> | ||
| 196 |   : MarshallingInfo<kpm, defaultvalue> { | ||
| 197 | code Normalizer = "normalizeSimpleFlag"; | ||
| 198 | code Denormalizer = "denormalizeSimpleFlag"; | ||
| 199 | } | ||
| 200 | |||
| 201 | // Marshalled option - single negative flag. | ||
| 202 | class MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true"> | ||
| 203 |   : MarshallingInfo<kpm, defaultvalue> { | ||
| 204 | code Normalizer = "normalizeSimpleNegativeFlag"; | ||
| 205 | code Denormalizer = "denormalizeSimpleFlag"; | ||
| 206 | } | ||
| 207 | |||
| 208 | // Marshalled option - single flag contributing to a bitfield. | ||
| 209 | class MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value> | ||
| 210 |   : MarshallingInfoFlag<kpm, "0u"> { | ||
| 211 |   code Normalizer = "makeFlagToValueNormalizer("#value#")"; | ||
| 212 | code ValueMerger = "mergeMaskValue"; | ||
| 213 |   code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)"; | ||
| 214 | } | ||
| 215 | |||
| 216 | // Implementation detail of BoolOption. | ||
| 217 | class MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value, | ||
| 218 | code other_value, code other_name> | ||
| 219 |   : MarshallingInfoFlag<kpm, defaultvalue> { | ||
| 220 |   code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")"; | ||
| 221 |   code Denormalizer = "makeBooleanOptionDenormalizer("#value#")"; | ||
| 222 | } | ||
| 223 | |||
| 224 | // Marshalled option accepting any of the specified enum values. | ||
| 225 | // Typically used with `Values`, `NormalizedValues` and `NormalizedValuesScope`. | ||
| 226 | class MarshallingInfoEnum<KeyPathAndMacro kpm, code defaultvalue> | ||
| 227 |   : MarshallingInfo<kpm, defaultvalue> { | ||
| 228 | code Normalizer = "normalizeSimpleEnum"; | ||
| 229 | code Denormalizer = "denormalizeSimpleEnum"; | ||
| 230 | } | ||
| 231 | |||
| 232 | // Mixins for additional marshalling attributes. | ||
| 233 | |||
| 234 | class ShouldParseIf<code condition> { code ShouldParse = condition; } | ||
| 235 | class AlwaysEmit { bit ShouldAlwaysEmit = true; } | ||
| 236 | class Normalizer<code normalizer> { code Normalizer = normalizer; } | ||
| 237 | class Denormalizer<code denormalizer> { code Denormalizer = denormalizer; } | ||
| 238 | class NormalizedValuesScope<code scope> { code NormalizedValuesScope = scope; } | ||
| 239 | class NormalizedValues<list<code> definitions> { list<code> NormalizedValues = definitions; }  | ||
| 240 | class ValueMerger<code merger> { code ValueMerger = merger; } | ||
| 241 | class ValueExtractor<code extractor> { code ValueExtractor = extractor; } | ||
| 242 | |||
| 243 | // Predefined options. | ||
| 244 | |||
| 245 | // FIXME: Have generator validate that these appear in correct position (and | ||
| 246 | // aren't duplicated). | ||
| 247 | def INPUT : Option<[], "<input>", KIND_INPUT>; | ||
| 248 | def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>; |