Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 1 | =========================== |
| 2 | TableGen Language Reference |
| 3 | =========================== |
| 4 | |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 5 | .. contents:: |
| 6 | :local: |
| 7 | |
| 8 | .. warning:: |
| 9 | This document is extremely rough. If you find something lacking, please |
Tanya Lattner | 377a984 | 2015-08-05 03:51:17 +0000 | [diff] [blame] | 10 | fix it, file a documentation bug, or ask about it on llvm-dev. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 11 | |
| 12 | Introduction |
| 13 | ============ |
| 14 | |
| 15 | This document is meant to be a normative spec about the TableGen language |
| 16 | in and of itself (i.e. how to understand a given construct in terms of how |
| 17 | it affects the final set of records represented by the TableGen file). If |
| 18 | you are unsure if this document is really what you are looking for, please |
Sean Silva | b9a65fd | 2014-04-07 22:46:40 +0000 | [diff] [blame] | 19 | read the :doc:`introduction to TableGen <index>` first. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 20 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 21 | Notation |
| 22 | ======== |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 23 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 24 | The lexical and syntax notation used here is intended to imitate |
| 25 | `Python's`_. In particular, for lexical definitions, the productions |
| 26 | operate at the character level and there is no implied whitespace between |
| 27 | elements. The syntax definitions operate at the token level, so there is |
| 28 | implied whitespace between tokens. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 29 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 30 | .. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 31 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 32 | Lexical Analysis |
| 33 | ================ |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 34 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 35 | TableGen supports BCPL (``// ...``) and nestable C-style (``/* ... */``) |
Vyacheslav Zakharin | 6c99d2b | 2018-11-27 18:57:43 +0000 | [diff] [blame] | 36 | comments. TableGen also provides simple `Preprocessing Support`_. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 37 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 38 | The following is a listing of the basic punctuation tokens:: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 39 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 40 | - + [ ] { } ( ) < > : ; . = ? # |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 41 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 42 | Numeric literals take one of the following forms: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 43 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 44 | .. TableGen actually will lex some pretty strange sequences an interpret |
| 45 | them as numbers. What is shown here is an attempt to approximate what it |
| 46 | "should" accept. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 47 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 48 | .. productionlist:: |
| 49 | TokInteger: `DecimalInteger` | `HexInteger` | `BinInteger` |
| 50 | DecimalInteger: ["+" | "-"] ("0"..."9")+ |
| 51 | HexInteger: "0x" ("0"..."9" | "a"..."f" | "A"..."F")+ |
| 52 | BinInteger: "0b" ("0" | "1")+ |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 53 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 54 | One aspect to note is that the :token:`DecimalInteger` token *includes* the |
| 55 | ``+`` or ``-``, as opposed to having ``+`` and ``-`` be unary operators as |
| 56 | most languages do. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 57 | |
Pete Cooper | e216468 | 2014-08-07 05:47:13 +0000 | [diff] [blame] | 58 | Also note that :token:`BinInteger` creates a value of type ``bits<n>`` |
| 59 | (where ``n`` is the number of bits). This will implicitly convert to |
| 60 | integers when needed. |
| 61 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 62 | TableGen has identifier-like tokens: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 63 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 64 | .. productionlist:: |
| 65 | ualpha: "a"..."z" | "A"..."Z" | "_" |
| 66 | TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")* |
| 67 | TokVarName: "$" `ualpha` (`ualpha` | "0"..."9")* |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 68 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 69 | Note that unlike most languages, TableGen allows :token:`TokIdentifier` to |
| 70 | begin with a number. In case of ambiguity, a token will be interpreted as a |
| 71 | numeric literal rather than an identifier. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 72 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 73 | TableGen also has two string-like literals: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 74 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 75 | .. productionlist:: |
| 76 | TokString: '"' <non-'"' characters and C-like escapes> '"' |
| 77 | TokCodeFragment: "[{" <shortest text not containing "}]"> "}]" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 78 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 79 | :token:`TokCodeFragment` is essentially a multiline string literal |
| 80 | delimited by ``[{`` and ``}]``. |
Sean Silva | f408f0f | 2014-02-09 02:43:50 +0000 | [diff] [blame] | 81 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 82 | .. note:: |
| 83 | The current implementation accepts the following C-like escapes:: |
Sean Silva | 104f2b5 | 2013-01-09 02:20:30 +0000 | [diff] [blame] | 84 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 85 | \\ \' \" \t \n |
Sean Silva | 104f2b5 | 2013-01-09 02:20:30 +0000 | [diff] [blame] | 86 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 87 | TableGen also has the following keywords:: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 88 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 89 | bit bits class code dag |
| 90 | def foreach defm field in |
| 91 | int let list multiclass string |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 92 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 93 | TableGen also has "bang operators" which have a |
| 94 | wide variety of meanings: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 95 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 96 | .. productionlist:: |
| 97 | BangOperator: one of |
| 98 | :!eq !if !head !tail !con |
Joerg Sonnenberger | b9f3466 | 2014-09-03 13:17:03 +0000 | [diff] [blame] | 99 | :!add !shl !sra !srl !and |
Matt Arsenault | ee23318 | 2016-11-15 06:49:28 +0000 | [diff] [blame] | 100 | :!or !empty !subst !foreach !strconcat |
Nicolai Haehnle | 8498a49 | 2018-03-06 13:49:16 +0000 | [diff] [blame] | 101 | :!cast !listconcat !size !foldl |
Nicolai Haehnle | af0de50 | 2018-03-14 11:00:57 +0000 | [diff] [blame] | 102 | :!isa !dag !le !lt !ge |
| 103 | :!gt !ne |
Matt Arsenault | ee23318 | 2016-11-15 06:49:28 +0000 | [diff] [blame] | 104 | |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 105 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 106 | Syntax |
| 107 | ====== |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 108 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 109 | TableGen has an ``include`` mechanism. It does not play a role in the |
| 110 | syntax per se, since it is lexically replaced with the contents of the |
| 111 | included file. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 112 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 113 | .. productionlist:: |
| 114 | IncludeDirective: "include" `TokString` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 115 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 116 | TableGen's top-level production consists of "objects". |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 117 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 118 | .. productionlist:: |
| 119 | TableGenFile: `Object`* |
Nicolai Haehnle | d66fa2a | 2018-03-09 12:24:42 +0000 | [diff] [blame] | 120 | Object: `Class` | `Def` | `Defm` | `Defset` | `Let` | `MultiClass` | |
| 121 | `Foreach` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 122 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 123 | ``class``\es |
| 124 | ------------ |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 125 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 126 | .. productionlist:: |
| 127 | Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody` |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 128 | TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 129 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 130 | A ``class`` declaration creates a record which other records can inherit |
| 131 | from. A class can be parametrized by a list of "template arguments", whose |
| 132 | values can be used in the class body. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 133 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 134 | A given class can only be defined once. A ``class`` declaration is |
| 135 | considered to define the class if any of the following is true: |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 136 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 137 | .. break ObjectBody into its consituents so that they are present here? |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 138 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 139 | #. The :token:`TemplateArgList` is present. |
| 140 | #. The :token:`Body` in the :token:`ObjectBody` is present and is not empty. |
| 141 | #. The :token:`BaseClassList` in the :token:`ObjectBody` is present. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 142 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 143 | You can declare an empty class by giving and empty :token:`TemplateArgList` |
| 144 | and an empty :token:`ObjectBody`. This can serve as a restricted form of |
| 145 | forward declaration: note that records deriving from the forward-declared |
| 146 | class will inherit no fields from it since the record expansion is done |
| 147 | when the record is parsed. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 148 | |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 149 | Every class has an implicit template argument called ``NAME``, which is set |
| 150 | to the name of the instantiating ``def`` or ``defm``. The result is undefined |
| 151 | if the class is instantiated by an anonymous record. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 152 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 153 | Declarations |
| 154 | ------------ |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 155 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 156 | .. Omitting mention of arcane "field" prefix to discourage its use. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 157 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 158 | The declaration syntax is pretty much what you would expect as a C++ |
| 159 | programmer. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 160 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 161 | .. productionlist:: |
| 162 | Declaration: `Type` `TokIdentifier` ["=" `Value`] |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 163 | |
Sylvestre Ledru | e0f2f60 | 2016-07-02 19:28:40 +0000 | [diff] [blame] | 164 | It assigns the value to the identifier. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 165 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 166 | Types |
| 167 | ----- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 168 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 169 | .. productionlist:: |
| 170 | Type: "string" | "code" | "bit" | "int" | "dag" |
| 171 | :| "bits" "<" `TokInteger` ">" |
| 172 | :| "list" "<" `Type` ">" |
| 173 | :| `ClassID` |
| 174 | ClassID: `TokIdentifier` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 175 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 176 | Both ``string`` and ``code`` correspond to the string type; the difference |
| 177 | is purely to indicate programmer intention. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 178 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 179 | The :token:`ClassID` must identify a class that has been previously |
| 180 | declared or defined. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 181 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 182 | Values |
| 183 | ------ |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 184 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 185 | .. productionlist:: |
| 186 | Value: `SimpleValue` `ValueSuffix`* |
| 187 | ValueSuffix: "{" `RangeList` "}" |
| 188 | :| "[" `RangeList` "]" |
| 189 | :| "." `TokIdentifier` |
| 190 | RangeList: `RangePiece` ("," `RangePiece`)* |
| 191 | RangePiece: `TokInteger` |
| 192 | :| `TokInteger` "-" `TokInteger` |
| 193 | :| `TokInteger` `TokInteger` |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 194 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 195 | The peculiar last form of :token:`RangePiece` is due to the fact that the |
| 196 | "``-``" is included in the :token:`TokInteger`, hence ``1-5`` gets lexed as |
| 197 | two consecutive :token:`TokInteger`'s, with values ``1`` and ``-5``, |
| 198 | instead of "1", "-", and "5". |
| 199 | The :token:`RangeList` can be thought of as specifying "list slice" in some |
| 200 | contexts. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 201 | |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 202 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 203 | :token:`SimpleValue` has a number of forms: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 204 | |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 205 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 206 | .. productionlist:: |
| 207 | SimpleValue: `TokIdentifier` |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 208 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 209 | The value will be the variable referenced by the identifier. It can be one |
| 210 | of: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 211 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 212 | .. The code for this is exceptionally abstruse. These examples are a |
| 213 | best-effort attempt. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 214 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 215 | * name of a ``def``, such as the use of ``Bar`` in:: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 216 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 217 | def Bar : SomeClass { |
| 218 | int X = 5; |
| 219 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 220 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 221 | def Foo { |
| 222 | SomeClass Baz = Bar; |
| 223 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 224 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 225 | * value local to a ``def``, such as the use of ``Bar`` in:: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 226 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 227 | def Foo { |
| 228 | int Bar = 5; |
| 229 | int Baz = Bar; |
| 230 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 231 | |
Nicolai Haehnle | 6b71fcb | 2018-06-04 14:26:12 +0000 | [diff] [blame] | 232 | Values defined in superclasses can be accessed the same way. |
| 233 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 234 | * a template arg of a ``class``, such as the use of ``Bar`` in:: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 235 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 236 | class Foo<int Bar> { |
| 237 | int Baz = Bar; |
| 238 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 239 | |
Nicolai Haehnle | 6b71fcb | 2018-06-04 14:26:12 +0000 | [diff] [blame] | 240 | * value local to a ``class``, such as the use of ``Bar`` in:: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 241 | |
Nicolai Haehnle | 6b71fcb | 2018-06-04 14:26:12 +0000 | [diff] [blame] | 242 | class Foo { |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 243 | int Bar = 5; |
| 244 | int Baz = Bar; |
| 245 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 246 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 247 | * a template arg to a ``multiclass``, such as the use of ``Bar`` in:: |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 248 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 249 | multiclass Foo<int Bar> { |
Nicolai Haehnle | 6b71fcb | 2018-06-04 14:26:12 +0000 | [diff] [blame] | 250 | def : SomeClass<Bar>; |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 251 | } |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 252 | |
Nicolai Haehnle | 6b71fcb | 2018-06-04 14:26:12 +0000 | [diff] [blame] | 253 | * the iteration variable of a ``foreach``, such as the use of ``i`` in:: |
| 254 | |
| 255 | foreach i = 0-5 in |
| 256 | def Foo#i; |
| 257 | |
| 258 | * a variable defined by ``defset`` |
| 259 | |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 260 | * the implicit template argument ``NAME`` in a ``class`` or ``multiclass`` |
| 261 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 262 | .. productionlist:: |
| 263 | SimpleValue: `TokInteger` |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 264 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 265 | This represents the numeric value of the integer. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 266 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 267 | .. productionlist:: |
| 268 | SimpleValue: `TokString`+ |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 269 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 270 | Multiple adjacent string literals are concatenated like in C/C++. The value |
| 271 | is the concatenation of the strings. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 272 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 273 | .. productionlist:: |
| 274 | SimpleValue: `TokCodeFragment` |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 275 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 276 | The value is the string value of the code fragment. |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 277 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 278 | .. productionlist:: |
| 279 | SimpleValue: "?" |
Renato Golin | 1625937 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 280 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 281 | ``?`` represents an "unset" initializer. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 282 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 283 | .. productionlist:: |
| 284 | SimpleValue: "{" `ValueList` "}" |
| 285 | ValueList: [`ValueListNE`] |
| 286 | ValueListNE: `Value` ("," `Value`)* |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 287 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 288 | This represents a sequence of bits, as would be used to initialize a |
| 289 | ``bits<n>`` field (where ``n`` is the number of bits). |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 290 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 291 | .. productionlist:: |
| 292 | SimpleValue: `ClassID` "<" `ValueListNE` ">" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 293 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 294 | This generates a new anonymous record definition (as would be created by an |
| 295 | unnamed ``def`` inheriting from the given class with the given template |
| 296 | arguments) and the value is the value of that record definition. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 297 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 298 | .. productionlist:: |
| 299 | SimpleValue: "[" `ValueList` "]" ["<" `Type` ">"] |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 300 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 301 | A list initializer. The optional :token:`Type` can be used to indicate a |
| 302 | specific element type, otherwise the element type will be deduced from the |
| 303 | given values. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 304 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 305 | .. The initial `DagArg` of the dag must start with an identifier or |
| 306 | !cast, but this is more of an implementation detail and so for now just |
| 307 | leave it out. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 308 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 309 | .. productionlist:: |
Simon Tatham | 0a556c8 | 2018-04-23 09:15:47 +0000 | [diff] [blame] | 310 | SimpleValue: "(" `DagArg` [`DagArgList`] ")" |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 311 | DagArgList: `DagArg` ("," `DagArg`)* |
| 312 | DagArg: `Value` [":" `TokVarName`] | `TokVarName` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 313 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 314 | The initial :token:`DagArg` is called the "operator" of the dag. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 315 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 316 | .. productionlist:: |
| 317 | SimpleValue: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 318 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 319 | Bodies |
| 320 | ------ |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 321 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 322 | .. productionlist:: |
| 323 | ObjectBody: `BaseClassList` `Body` |
| 324 | BaseClassList: [":" `BaseClassListNE`] |
| 325 | BaseClassListNE: `SubClassRef` ("," `SubClassRef`)* |
| 326 | SubClassRef: (`ClassID` | `MultiClassID`) ["<" `ValueList` ">"] |
| 327 | DefmID: `TokIdentifier` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 328 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 329 | The version with the :token:`MultiClassID` is only valid in the |
| 330 | :token:`BaseClassList` of a ``defm``. |
| 331 | The :token:`MultiClassID` should be the name of a ``multiclass``. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 332 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 333 | .. put this somewhere else |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 334 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 335 | It is after parsing the base class list that the "let stack" is applied. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 336 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 337 | .. productionlist:: |
| 338 | Body: ";" | "{" BodyList "}" |
| 339 | BodyList: BodyItem* |
| 340 | BodyItem: `Declaration` ";" |
Simon Tatham | 0a556c8 | 2018-04-23 09:15:47 +0000 | [diff] [blame] | 341 | :| "let" `TokIdentifier` [ "{" `RangeList` "}" ] "=" `Value` ";" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 342 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 343 | The ``let`` form allows overriding the value of an inherited field. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 344 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 345 | ``def`` |
| 346 | ------- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 347 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 348 | .. productionlist:: |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 349 | Def: "def" [`Value`] `ObjectBody` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 350 | |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 351 | Defines a record whose name is given by the optional :token:`Value`. The value |
| 352 | is parsed in a special mode where global identifiers (records and variables |
| 353 | defined by ``defset``) are not recognized, and all unrecognized identifiers |
| 354 | are interpreted as strings. |
| 355 | |
| 356 | If no name is given, the record is anonymous. The final name of anonymous |
| 357 | records is undefined, but globally unique. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 358 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 359 | Special handling occurs if this ``def`` appears inside a ``multiclass`` or |
| 360 | a ``foreach``. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 361 | |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 362 | When a non-anonymous record is defined in a multiclass and the given name |
| 363 | does not contain a reference to the implicit template argument ``NAME``, such |
| 364 | a reference will automatically be prepended. That is, the following are |
| 365 | equivalent inside a multiclass:: |
| 366 | |
| 367 | def Foo; |
| 368 | def NAME#Foo; |
| 369 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 370 | ``defm`` |
| 371 | -------- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 372 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 373 | .. productionlist:: |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 374 | Defm: "defm" [`Value`] ":" `BaseClassListNE` ";" |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 375 | |
Nicolai Haehnle | 26db53e | 2018-06-04 14:26:05 +0000 | [diff] [blame] | 376 | The :token:`BaseClassList` is a list of at least one ``multiclass`` and any |
| 377 | number of ``class``'s. The ``multiclass``'s must occur before any ``class``'s. |
| 378 | |
| 379 | Instantiates all records defined in all given ``multiclass``'s and adds the |
| 380 | given ``class``'s as superclasses. |
| 381 | |
| 382 | The name is parsed in the same special mode used by ``def``. If the name is |
| 383 | missing, a globally unique string is used instead (but instantiated records |
| 384 | are not considered to be anonymous, unless they were originally defined by an |
| 385 | anonymous ``def``) That is, the following have different semantics:: |
| 386 | |
| 387 | defm : SomeMultiClass<...>; // some globally unique name |
| 388 | defm "" : SomeMultiClass<...>; // empty name string |
| 389 | |
| 390 | When it occurs inside a multiclass, the second variant is equivalent to |
| 391 | ``defm NAME : ...``. More generally, when ``defm`` occurs in a multiclass and |
| 392 | its name does not contain a reference to the implicit template argument |
| 393 | ``NAME``, such a reference will automatically be prepended. That is, the |
| 394 | following are equivalent inside a multiclass:: |
| 395 | |
| 396 | defm Foo : SomeMultiClass<...>; |
| 397 | defm NAME#Foo : SomeMultiClass<...>; |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 398 | |
Nicolai Haehnle | d66fa2a | 2018-03-09 12:24:42 +0000 | [diff] [blame] | 399 | ``defset`` |
| 400 | ---------- |
| 401 | .. productionlist:: |
| 402 | Defset: "defset" `Type` `TokIdentifier` "=" "{" `Object`* "}" |
| 403 | |
| 404 | All records defined inside the braces via ``def`` and ``defm`` are collected |
| 405 | in a globally accessible list of the given name (in addition to being added |
| 406 | to the global collection of records as usual). Anonymous records created inside |
| 407 | initializier expressions using the ``Class<args...>`` syntax are never collected |
| 408 | in a defset. |
| 409 | |
| 410 | The given type must be ``list<A>``, where ``A`` is some class. It is an error |
| 411 | to define a record (via ``def`` or ``defm``) inside the braces which doesn't |
| 412 | derive from ``A``. |
| 413 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 414 | ``foreach`` |
| 415 | ----------- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 416 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 417 | .. productionlist:: |
Nicolai Haehnle | ad64c88 | 2018-03-09 12:24:30 +0000 | [diff] [blame] | 418 | Foreach: "foreach" `ForeachDeclaration` "in" "{" `Object`* "}" |
| 419 | :| "foreach" `ForeachDeclaration` "in" `Object` |
| 420 | ForeachDeclaration: ID "=" ( "{" `RangeList` "}" | `RangePiece` | `Value` ) |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 421 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 422 | The value assigned to the variable in the declaration is iterated over and |
| 423 | the object or object list is reevaluated with the variable set at each |
| 424 | iterated value. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 425 | |
Nicolai Haehnle | ad64c88 | 2018-03-09 12:24:30 +0000 | [diff] [blame] | 426 | Note that the productions involving RangeList and RangePiece have precedence |
| 427 | over the more generic value parsing based on the first token. |
| 428 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 429 | Top-Level ``let`` |
| 430 | ----------------- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 431 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 432 | .. productionlist:: |
| 433 | Let: "let" `LetList` "in" "{" `Object`* "}" |
| 434 | :| "let" `LetList` "in" `Object` |
| 435 | LetList: `LetItem` ("," `LetItem`)* |
| 436 | LetItem: `TokIdentifier` [`RangeList`] "=" `Value` |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 437 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 438 | This is effectively equivalent to ``let`` inside the body of a record |
| 439 | except that it applies to multiple records at a time. The bindings are |
| 440 | applied at the end of parsing the base classes of a record. |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 441 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 442 | ``multiclass`` |
| 443 | -------------- |
Sean Silva | 26b8aab | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 444 | |
Renato Golin | a5b283a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 445 | .. productionlist:: |
| 446 | MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`] |
| 447 | : [":" `BaseMultiClassList`] "{" `MultiClassObject`+ "}" |
| 448 | BaseMultiClassList: `MultiClassID` ("," `MultiClassID`)* |
| 449 | MultiClassID: `TokIdentifier` |
| 450 | MultiClassObject: `Def` | `Defm` | `Let` | `Foreach` |
Vyacheslav Zakharin | 6c99d2b | 2018-11-27 18:57:43 +0000 | [diff] [blame] | 451 | |
| 452 | Preprocessing Support |
| 453 | ===================== |
| 454 | |
| 455 | TableGen's embedded preprocessor is only intended for conditional compilation. |
| 456 | It supports the following directives: |
| 457 | |
| 458 | .. productionlist:: |
| 459 | LineBegin: ^ |
| 460 | LineEnd: "\n" | "\r" | EOF |
| 461 | WhiteSpace: " " | "\t" |
| 462 | CStyleComment: "/*" (.* - "*/") "*/" |
| 463 | BCPLComment: "//" (.* - `LineEnd`) `LineEnd` |
| 464 | WhiteSpaceOrCStyleComment: `WhiteSpace` | `CStyleComment` |
| 465 | WhiteSpaceOrAnyComment: `WhiteSpace` | `CStyleComment` | `BCPLComment` |
| 466 | MacroName: `ualpha` (`ualpha` | "0"..."9")* |
| 467 | PrepDefine: `LineBegin` (`WhiteSpaceOrCStyleComment`)* |
| 468 | : "#define" (`WhiteSpace`)+ `MacroName` |
| 469 | : (`WhiteSpaceOrAnyComment`)* `LineEnd` |
| 470 | PrepIfdef: `LineBegin` (`WhiteSpaceOrCStyleComment`)* |
| 471 | : "#ifdef" (`WhiteSpace`)+ `MacroName` |
| 472 | : (`WhiteSpaceOrAnyComment`)* `LineEnd` |
| 473 | PrepElse: `LineBegin` (`WhiteSpaceOrCStyleComment`)* |
| 474 | : "#else" (`WhiteSpaceOrAnyComment`)* `LineEnd` |
| 475 | PrepEndif: `LineBegin` (`WhiteSpaceOrCStyleComment`)* |
| 476 | : "#endif" (`WhiteSpaceOrAnyComment`)* `LineEnd` |
| 477 | PrepRegContentException: `PredIfdef` | `PredElse` | `PredEndif` | EOF |
| 478 | PrepRegion: .* - `PrepRegContentException` |
| 479 | :| `PrepIfDef` |
| 480 | : (`PrepRegion`)* |
| 481 | : [`PrepElse`] |
| 482 | : (`PrepRegion`)* |
| 483 | : `PrepEndif` |
| 484 | |
| 485 | :token:`PrepRegion` may occur anywhere in a TD file, as long as it matches |
| 486 | the grammar specification. |
| 487 | |
| 488 | :token:`PrepDefine` allows defining a :token:`MacroName` so that any following |
| 489 | :token:`PrepIfdef` - :token:`PrepElse` preprocessing region part and |
| 490 | :token:`PrepIfdef` - :token:`PrepEndif` preprocessing region |
| 491 | are enabled for TableGen tokens parsing. |
| 492 | |
| 493 | A preprocessing region, starting (i.e. having its :token:`PrepIfdef`) in a file, |
| 494 | must end (i.e. have its :token:`PrepEndif`) in the same file. |
| 495 | |
| 496 | A :token:`MacroName` may be defined externally by using ``{ -D<NAME> }`` |
| 497 | option of TableGen. |