blob: 9b074be38dcd46d5af6e76215155a04896e8f157 [file] [log] [blame]
Sean Silva1b600182013-01-07 02:43:44 +00001===========================
2TableGen Language Reference
3===========================
4
Sean Silva1b600182013-01-07 02:43:44 +00005.. contents::
6 :local:
7
8.. warning::
9 This document is extremely rough. If you find something lacking, please
10 fix it, file a documentation bug, or ask about it on llvmdev.
11
12Introduction
13============
14
15This document is meant to be a normative spec about the TableGen language
16in and of itself (i.e. how to understand a given construct in terms of how
17it affects the final set of records represented by the TableGen file). If
18you are unsure if this document is really what you are looking for, please
Sean Silva397ee6e2014-04-07 22:46:40 +000019read the :doc:`introduction to TableGen <index>` first.
Sean Silva1b600182013-01-07 02:43:44 +000020
Renato Golin33f973a2014-04-01 09:51:49 +000021Notation
22========
Sean Silva1b600182013-01-07 02:43:44 +000023
Renato Golin33f973a2014-04-01 09:51:49 +000024The lexical and syntax notation used here is intended to imitate
25`Python's`_. In particular, for lexical definitions, the productions
26operate at the character level and there is no implied whitespace between
27elements. The syntax definitions operate at the token level, so there is
28implied whitespace between tokens.
Sean Silva1b600182013-01-07 02:43:44 +000029
Renato Golin33f973a2014-04-01 09:51:49 +000030.. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation
Sean Silva1b600182013-01-07 02:43:44 +000031
Renato Golin33f973a2014-04-01 09:51:49 +000032Lexical Analysis
33================
Sean Silva1b600182013-01-07 02:43:44 +000034
Renato Golin33f973a2014-04-01 09:51:49 +000035TableGen supports BCPL (``// ...``) and nestable C-style (``/* ... */``)
36comments.
Sean Silva1b600182013-01-07 02:43:44 +000037
Renato Golin33f973a2014-04-01 09:51:49 +000038The following is a listing of the basic punctuation tokens::
Sean Silva1b600182013-01-07 02:43:44 +000039
Renato Golin33f973a2014-04-01 09:51:49 +000040 - + [ ] { } ( ) < > : ; . = ? #
Sean Silva1b600182013-01-07 02:43:44 +000041
Renato Golin33f973a2014-04-01 09:51:49 +000042Numeric literals take one of the following forms:
Sean Silva1b600182013-01-07 02:43:44 +000043
Renato Golin33f973a2014-04-01 09:51:49 +000044.. 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 Silva1b600182013-01-07 02:43:44 +000047
Renato Golin33f973a2014-04-01 09:51:49 +000048.. 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 Silva1b600182013-01-07 02:43:44 +000053
Renato Golin33f973a2014-04-01 09:51:49 +000054One aspect to note is that the :token:`DecimalInteger` token *includes* the
55``+`` or ``-``, as opposed to having ``+`` and ``-`` be unary operators as
56most languages do.
Sean Silva1b600182013-01-07 02:43:44 +000057
Renato Golin33f973a2014-04-01 09:51:49 +000058TableGen has identifier-like tokens:
Sean Silva1b600182013-01-07 02:43:44 +000059
Renato Golin33f973a2014-04-01 09:51:49 +000060.. productionlist::
61 ualpha: "a"..."z" | "A"..."Z" | "_"
62 TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")*
63 TokVarName: "$" `ualpha` (`ualpha` | "0"..."9")*
Sean Silva1b600182013-01-07 02:43:44 +000064
Renato Golin33f973a2014-04-01 09:51:49 +000065Note that unlike most languages, TableGen allows :token:`TokIdentifier` to
66begin with a number. In case of ambiguity, a token will be interpreted as a
67numeric literal rather than an identifier.
Sean Silva1b600182013-01-07 02:43:44 +000068
Renato Golin33f973a2014-04-01 09:51:49 +000069TableGen also has two string-like literals:
Sean Silva1b600182013-01-07 02:43:44 +000070
Renato Golin33f973a2014-04-01 09:51:49 +000071.. productionlist::
72 TokString: '"' <non-'"' characters and C-like escapes> '"'
73 TokCodeFragment: "[{" <shortest text not containing "}]"> "}]"
Sean Silva1b600182013-01-07 02:43:44 +000074
Renato Golin33f973a2014-04-01 09:51:49 +000075:token:`TokCodeFragment` is essentially a multiline string literal
76delimited by ``[{`` and ``}]``.
Sean Silvacc373352014-02-09 02:43:50 +000077
Renato Golin33f973a2014-04-01 09:51:49 +000078.. note::
79 The current implementation accepts the following C-like escapes::
Sean Silva543fd7f2013-01-09 02:20:30 +000080
Renato Golin33f973a2014-04-01 09:51:49 +000081 \\ \' \" \t \n
Sean Silva543fd7f2013-01-09 02:20:30 +000082
Renato Golin33f973a2014-04-01 09:51:49 +000083TableGen also has the following keywords::
Sean Silva1b600182013-01-07 02:43:44 +000084
Renato Golin33f973a2014-04-01 09:51:49 +000085 bit bits class code dag
86 def foreach defm field in
87 int let list multiclass string
Sean Silva1b600182013-01-07 02:43:44 +000088
Renato Golin33f973a2014-04-01 09:51:49 +000089TableGen also has "bang operators" which have a
90wide variety of meanings:
Sean Silva1b600182013-01-07 02:43:44 +000091
Renato Golin33f973a2014-04-01 09:51:49 +000092.. productionlist::
93 BangOperator: one of
94 :!eq !if !head !tail !con
95 :!add !shl !sra !srl
Daniel Sanders314e80e2014-05-07 10:13:19 +000096 :!cast !empty !subst !foreach !listconcat !strconcat
Sean Silva1b600182013-01-07 02:43:44 +000097
Renato Golin33f973a2014-04-01 09:51:49 +000098Syntax
99======
Sean Silva1b600182013-01-07 02:43:44 +0000100
Renato Golin33f973a2014-04-01 09:51:49 +0000101TableGen has an ``include`` mechanism. It does not play a role in the
102syntax per se, since it is lexically replaced with the contents of the
103included file.
Sean Silva1b600182013-01-07 02:43:44 +0000104
Renato Golin33f973a2014-04-01 09:51:49 +0000105.. productionlist::
106 IncludeDirective: "include" `TokString`
Sean Silva1b600182013-01-07 02:43:44 +0000107
Renato Golin33f973a2014-04-01 09:51:49 +0000108TableGen's top-level production consists of "objects".
Sean Silva1b600182013-01-07 02:43:44 +0000109
Renato Golin33f973a2014-04-01 09:51:49 +0000110.. productionlist::
111 TableGenFile: `Object`*
112 Object: `Class` | `Def` | `Defm` | `Let` | `MultiClass` | `Foreach`
Sean Silva1b600182013-01-07 02:43:44 +0000113
Renato Golin33f973a2014-04-01 09:51:49 +0000114``class``\es
115------------
Sean Silva1b600182013-01-07 02:43:44 +0000116
Renato Golin33f973a2014-04-01 09:51:49 +0000117.. productionlist::
118 Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000119
Renato Golin33f973a2014-04-01 09:51:49 +0000120A ``class`` declaration creates a record which other records can inherit
121from. A class can be parametrized by a list of "template arguments", whose
122values can be used in the class body.
Sean Silva1b600182013-01-07 02:43:44 +0000123
Renato Golin33f973a2014-04-01 09:51:49 +0000124A given class can only be defined once. A ``class`` declaration is
125considered to define the class if any of the following is true:
Sean Silva1b600182013-01-07 02:43:44 +0000126
Renato Golin33f973a2014-04-01 09:51:49 +0000127.. break ObjectBody into its consituents so that they are present here?
Sean Silva1b600182013-01-07 02:43:44 +0000128
Renato Golin33f973a2014-04-01 09:51:49 +0000129#. The :token:`TemplateArgList` is present.
130#. The :token:`Body` in the :token:`ObjectBody` is present and is not empty.
131#. The :token:`BaseClassList` in the :token:`ObjectBody` is present.
Sean Silva1b600182013-01-07 02:43:44 +0000132
Renato Golin33f973a2014-04-01 09:51:49 +0000133You can declare an empty class by giving and empty :token:`TemplateArgList`
134and an empty :token:`ObjectBody`. This can serve as a restricted form of
135forward declaration: note that records deriving from the forward-declared
136class will inherit no fields from it since the record expansion is done
137when the record is parsed.
Sean Silva1b600182013-01-07 02:43:44 +0000138
Renato Golin33f973a2014-04-01 09:51:49 +0000139.. productionlist::
140 TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">"
Sean Silva1b600182013-01-07 02:43:44 +0000141
Renato Golin33f973a2014-04-01 09:51:49 +0000142Declarations
143------------
Sean Silva1b600182013-01-07 02:43:44 +0000144
Renato Golin33f973a2014-04-01 09:51:49 +0000145.. Omitting mention of arcane "field" prefix to discourage its use.
Sean Silva1b600182013-01-07 02:43:44 +0000146
Renato Golin33f973a2014-04-01 09:51:49 +0000147The declaration syntax is pretty much what you would expect as a C++
148programmer.
Sean Silva1b600182013-01-07 02:43:44 +0000149
Renato Golin33f973a2014-04-01 09:51:49 +0000150.. productionlist::
151 Declaration: `Type` `TokIdentifier` ["=" `Value`]
Sean Silva1b600182013-01-07 02:43:44 +0000152
Renato Golin33f973a2014-04-01 09:51:49 +0000153It assigns the value to the identifer.
Sean Silva1b600182013-01-07 02:43:44 +0000154
Renato Golin33f973a2014-04-01 09:51:49 +0000155Types
156-----
Sean Silva1b600182013-01-07 02:43:44 +0000157
Renato Golin33f973a2014-04-01 09:51:49 +0000158.. productionlist::
159 Type: "string" | "code" | "bit" | "int" | "dag"
160 :| "bits" "<" `TokInteger` ">"
161 :| "list" "<" `Type` ">"
162 :| `ClassID`
163 ClassID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000164
Renato Golin33f973a2014-04-01 09:51:49 +0000165Both ``string`` and ``code`` correspond to the string type; the difference
166is purely to indicate programmer intention.
Renato Golinca105642014-03-20 16:08:34 +0000167
Renato Golin33f973a2014-04-01 09:51:49 +0000168The :token:`ClassID` must identify a class that has been previously
169declared or defined.
Renato Golinca105642014-03-20 16:08:34 +0000170
Renato Golin33f973a2014-04-01 09:51:49 +0000171Values
172------
Renato Golinca105642014-03-20 16:08:34 +0000173
Renato Golin33f973a2014-04-01 09:51:49 +0000174.. productionlist::
175 Value: `SimpleValue` `ValueSuffix`*
176 ValueSuffix: "{" `RangeList` "}"
177 :| "[" `RangeList` "]"
178 :| "." `TokIdentifier`
179 RangeList: `RangePiece` ("," `RangePiece`)*
180 RangePiece: `TokInteger`
181 :| `TokInteger` "-" `TokInteger`
182 :| `TokInteger` `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000183
Renato Golin33f973a2014-04-01 09:51:49 +0000184The peculiar last form of :token:`RangePiece` is due to the fact that the
185"``-``" is included in the :token:`TokInteger`, hence ``1-5`` gets lexed as
186two consecutive :token:`TokInteger`'s, with values ``1`` and ``-5``,
187instead of "1", "-", and "5".
188The :token:`RangeList` can be thought of as specifying "list slice" in some
189contexts.
Renato Golinca105642014-03-20 16:08:34 +0000190
Renato Golinca105642014-03-20 16:08:34 +0000191
Renato Golin33f973a2014-04-01 09:51:49 +0000192:token:`SimpleValue` has a number of forms:
Renato Golinca105642014-03-20 16:08:34 +0000193
Renato Golinca105642014-03-20 16:08:34 +0000194
Renato Golin33f973a2014-04-01 09:51:49 +0000195.. productionlist::
196 SimpleValue: `TokIdentifier`
Renato Golinca105642014-03-20 16:08:34 +0000197
Renato Golin33f973a2014-04-01 09:51:49 +0000198The value will be the variable referenced by the identifier. It can be one
199of:
Renato Golinca105642014-03-20 16:08:34 +0000200
Renato Golin33f973a2014-04-01 09:51:49 +0000201.. The code for this is exceptionally abstruse. These examples are a
202 best-effort attempt.
Renato Golinca105642014-03-20 16:08:34 +0000203
Renato Golin33f973a2014-04-01 09:51:49 +0000204* name of a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000205
Renato Golin33f973a2014-04-01 09:51:49 +0000206 def Bar : SomeClass {
207 int X = 5;
208 }
Renato Golinca105642014-03-20 16:08:34 +0000209
Renato Golin33f973a2014-04-01 09:51:49 +0000210 def Foo {
211 SomeClass Baz = Bar;
212 }
Renato Golinca105642014-03-20 16:08:34 +0000213
Renato Golin33f973a2014-04-01 09:51:49 +0000214* value local to a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000215
Renato Golin33f973a2014-04-01 09:51:49 +0000216 def Foo {
217 int Bar = 5;
218 int Baz = Bar;
219 }
Renato Golinca105642014-03-20 16:08:34 +0000220
Renato Golin33f973a2014-04-01 09:51:49 +0000221* a template arg of a ``class``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000222
Renato Golin33f973a2014-04-01 09:51:49 +0000223 class Foo<int Bar> {
224 int Baz = Bar;
225 }
Renato Golinca105642014-03-20 16:08:34 +0000226
Renato Golin33f973a2014-04-01 09:51:49 +0000227* value local to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000228
Renato Golin33f973a2014-04-01 09:51:49 +0000229 multiclass Foo {
230 int Bar = 5;
231 int Baz = Bar;
232 }
Renato Golinca105642014-03-20 16:08:34 +0000233
Renato Golin33f973a2014-04-01 09:51:49 +0000234* a template arg to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000235
Renato Golin33f973a2014-04-01 09:51:49 +0000236 multiclass Foo<int Bar> {
237 int Baz = Bar;
238 }
Renato Golinca105642014-03-20 16:08:34 +0000239
Renato Golin33f973a2014-04-01 09:51:49 +0000240.. productionlist::
241 SimpleValue: `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000242
Renato Golin33f973a2014-04-01 09:51:49 +0000243This represents the numeric value of the integer.
Renato Golinca105642014-03-20 16:08:34 +0000244
Renato Golin33f973a2014-04-01 09:51:49 +0000245.. productionlist::
246 SimpleValue: `TokString`+
Renato Golinca105642014-03-20 16:08:34 +0000247
Renato Golin33f973a2014-04-01 09:51:49 +0000248Multiple adjacent string literals are concatenated like in C/C++. The value
249is the concatenation of the strings.
Renato Golinca105642014-03-20 16:08:34 +0000250
Renato Golin33f973a2014-04-01 09:51:49 +0000251.. productionlist::
252 SimpleValue: `TokCodeFragment`
Renato Golinca105642014-03-20 16:08:34 +0000253
Renato Golin33f973a2014-04-01 09:51:49 +0000254The value is the string value of the code fragment.
Renato Golinca105642014-03-20 16:08:34 +0000255
Renato Golin33f973a2014-04-01 09:51:49 +0000256.. productionlist::
257 SimpleValue: "?"
Renato Golinca105642014-03-20 16:08:34 +0000258
Renato Golin33f973a2014-04-01 09:51:49 +0000259``?`` represents an "unset" initializer.
Sean Silva1b600182013-01-07 02:43:44 +0000260
Renato Golin33f973a2014-04-01 09:51:49 +0000261.. productionlist::
262 SimpleValue: "{" `ValueList` "}"
263 ValueList: [`ValueListNE`]
264 ValueListNE: `Value` ("," `Value`)*
Sean Silva1b600182013-01-07 02:43:44 +0000265
Renato Golin33f973a2014-04-01 09:51:49 +0000266This represents a sequence of bits, as would be used to initialize a
267``bits<n>`` field (where ``n`` is the number of bits).
Sean Silva1b600182013-01-07 02:43:44 +0000268
Renato Golin33f973a2014-04-01 09:51:49 +0000269.. productionlist::
270 SimpleValue: `ClassID` "<" `ValueListNE` ">"
Sean Silva1b600182013-01-07 02:43:44 +0000271
Renato Golin33f973a2014-04-01 09:51:49 +0000272This generates a new anonymous record definition (as would be created by an
273unnamed ``def`` inheriting from the given class with the given template
274arguments) and the value is the value of that record definition.
Sean Silva1b600182013-01-07 02:43:44 +0000275
Renato Golin33f973a2014-04-01 09:51:49 +0000276.. productionlist::
277 SimpleValue: "[" `ValueList` "]" ["<" `Type` ">"]
Sean Silva1b600182013-01-07 02:43:44 +0000278
Renato Golin33f973a2014-04-01 09:51:49 +0000279A list initializer. The optional :token:`Type` can be used to indicate a
280specific element type, otherwise the element type will be deduced from the
281given values.
Sean Silva1b600182013-01-07 02:43:44 +0000282
Renato Golin33f973a2014-04-01 09:51:49 +0000283.. The initial `DagArg` of the dag must start with an identifier or
284 !cast, but this is more of an implementation detail and so for now just
285 leave it out.
Sean Silva1b600182013-01-07 02:43:44 +0000286
Renato Golin33f973a2014-04-01 09:51:49 +0000287.. productionlist::
288 SimpleValue: "(" `DagArg` `DagArgList` ")"
289 DagArgList: `DagArg` ("," `DagArg`)*
290 DagArg: `Value` [":" `TokVarName`] | `TokVarName`
Sean Silva1b600182013-01-07 02:43:44 +0000291
Renato Golin33f973a2014-04-01 09:51:49 +0000292The initial :token:`DagArg` is called the "operator" of the dag.
Sean Silva1b600182013-01-07 02:43:44 +0000293
Renato Golin33f973a2014-04-01 09:51:49 +0000294.. productionlist::
295 SimpleValue: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")"
Sean Silva1b600182013-01-07 02:43:44 +0000296
Renato Golin33f973a2014-04-01 09:51:49 +0000297Bodies
298------
Sean Silva1b600182013-01-07 02:43:44 +0000299
Renato Golin33f973a2014-04-01 09:51:49 +0000300.. productionlist::
301 ObjectBody: `BaseClassList` `Body`
302 BaseClassList: [":" `BaseClassListNE`]
303 BaseClassListNE: `SubClassRef` ("," `SubClassRef`)*
304 SubClassRef: (`ClassID` | `MultiClassID`) ["<" `ValueList` ">"]
305 DefmID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000306
Renato Golin33f973a2014-04-01 09:51:49 +0000307The version with the :token:`MultiClassID` is only valid in the
308:token:`BaseClassList` of a ``defm``.
309The :token:`MultiClassID` should be the name of a ``multiclass``.
Sean Silva1b600182013-01-07 02:43:44 +0000310
Renato Golin33f973a2014-04-01 09:51:49 +0000311.. put this somewhere else
Sean Silva1b600182013-01-07 02:43:44 +0000312
Renato Golin33f973a2014-04-01 09:51:49 +0000313It is after parsing the base class list that the "let stack" is applied.
Sean Silva1b600182013-01-07 02:43:44 +0000314
Renato Golin33f973a2014-04-01 09:51:49 +0000315.. productionlist::
316 Body: ";" | "{" BodyList "}"
317 BodyList: BodyItem*
318 BodyItem: `Declaration` ";"
319 :| "let" `TokIdentifier` [`RangeList`] "=" `Value` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000320
Renato Golin33f973a2014-04-01 09:51:49 +0000321The ``let`` form allows overriding the value of an inherited field.
Sean Silva1b600182013-01-07 02:43:44 +0000322
Renato Golin33f973a2014-04-01 09:51:49 +0000323``def``
324-------
Sean Silva1b600182013-01-07 02:43:44 +0000325
Renato Golin33f973a2014-04-01 09:51:49 +0000326.. TODO::
327 There can be pastes in the names here, like ``#NAME#``. Look into that
328 and document it (it boils down to ParseIDValue with IDParseMode ==
329 ParseNameMode). ParseObjectName calls into the general ParseValue, with
330 the only different from "arbitrary expression parsing" being IDParseMode
331 == Mode.
Sean Silva1b600182013-01-07 02:43:44 +0000332
Renato Golin33f973a2014-04-01 09:51:49 +0000333.. productionlist::
334 Def: "def" `TokIdentifier` `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000335
Renato Golin33f973a2014-04-01 09:51:49 +0000336Defines a record whose name is given by the :token:`TokIdentifier`. The
337fields of the record are inherited from the base classes and defined in the
338body.
Sean Silva1b600182013-01-07 02:43:44 +0000339
Renato Golin33f973a2014-04-01 09:51:49 +0000340Special handling occurs if this ``def`` appears inside a ``multiclass`` or
341a ``foreach``.
Sean Silva1b600182013-01-07 02:43:44 +0000342
Renato Golin33f973a2014-04-01 09:51:49 +0000343``defm``
344--------
Sean Silva1b600182013-01-07 02:43:44 +0000345
Renato Golin33f973a2014-04-01 09:51:49 +0000346.. productionlist::
347 Defm: "defm" `TokIdentifier` ":" `BaseClassListNE` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000348
Renato Golin33f973a2014-04-01 09:51:49 +0000349Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must
350precede any ``class``'s that appear.
Sean Silva1b600182013-01-07 02:43:44 +0000351
Renato Golin33f973a2014-04-01 09:51:49 +0000352``foreach``
353-----------
Sean Silva1b600182013-01-07 02:43:44 +0000354
Renato Golin33f973a2014-04-01 09:51:49 +0000355.. productionlist::
356 Foreach: "foreach" `Declaration` "in" "{" `Object`* "}"
357 :| "foreach" `Declaration` "in" `Object`
Sean Silva1b600182013-01-07 02:43:44 +0000358
Renato Golin33f973a2014-04-01 09:51:49 +0000359The value assigned to the variable in the declaration is iterated over and
360the object or object list is reevaluated with the variable set at each
361iterated value.
Sean Silva1b600182013-01-07 02:43:44 +0000362
Renato Golin33f973a2014-04-01 09:51:49 +0000363Top-Level ``let``
364-----------------
Sean Silva1b600182013-01-07 02:43:44 +0000365
Renato Golin33f973a2014-04-01 09:51:49 +0000366.. productionlist::
367 Let: "let" `LetList` "in" "{" `Object`* "}"
368 :| "let" `LetList` "in" `Object`
369 LetList: `LetItem` ("," `LetItem`)*
370 LetItem: `TokIdentifier` [`RangeList`] "=" `Value`
Sean Silva1b600182013-01-07 02:43:44 +0000371
Renato Golin33f973a2014-04-01 09:51:49 +0000372This is effectively equivalent to ``let`` inside the body of a record
373except that it applies to multiple records at a time. The bindings are
374applied at the end of parsing the base classes of a record.
Sean Silva1b600182013-01-07 02:43:44 +0000375
Renato Golin33f973a2014-04-01 09:51:49 +0000376``multiclass``
377--------------
Sean Silva1b600182013-01-07 02:43:44 +0000378
Renato Golin33f973a2014-04-01 09:51:49 +0000379.. productionlist::
380 MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`]
381 : [":" `BaseMultiClassList`] "{" `MultiClassObject`+ "}"
382 BaseMultiClassList: `MultiClassID` ("," `MultiClassID`)*
383 MultiClassID: `TokIdentifier`
384 MultiClassObject: `Def` | `Defm` | `Let` | `Foreach`