blob: e3db3aa62712fae11a0d861699d03356b1c01d9d [file] [log] [blame]
Sean Silva1b600182013-01-07 02:43:44 +00001===========================
2TableGen Language Reference
3===========================
4
Renato Golin33f973a2014-04-01 09:51:49 +00005.. sectionauthor:: Sean Silva <silvas@purdue.edu>
6
Sean Silva1b600182013-01-07 02:43:44 +00007.. contents::
8 :local:
9
10.. warning::
11 This document is extremely rough. If you find something lacking, please
12 fix it, file a documentation bug, or ask about it on llvmdev.
13
14Introduction
15============
16
17This document is meant to be a normative spec about the TableGen language
18in and of itself (i.e. how to understand a given construct in terms of how
19it affects the final set of records represented by the TableGen file). If
20you are unsure if this document is really what you are looking for, please
Renato Golin33f973a2014-04-01 09:51:49 +000021read :doc:`/TableGenFundamentals` first.
Sean Silva1b600182013-01-07 02:43:44 +000022
Renato Golin33f973a2014-04-01 09:51:49 +000023Notation
24========
Sean Silva1b600182013-01-07 02:43:44 +000025
Renato Golin33f973a2014-04-01 09:51:49 +000026The lexical and syntax notation used here is intended to imitate
27`Python's`_. In particular, for lexical definitions, the productions
28operate at the character level and there is no implied whitespace between
29elements. The syntax definitions operate at the token level, so there is
30implied whitespace between tokens.
Sean Silva1b600182013-01-07 02:43:44 +000031
Renato Golin33f973a2014-04-01 09:51:49 +000032.. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation
Sean Silva1b600182013-01-07 02:43:44 +000033
Renato Golin33f973a2014-04-01 09:51:49 +000034Lexical Analysis
35================
Sean Silva1b600182013-01-07 02:43:44 +000036
Renato Golin33f973a2014-04-01 09:51:49 +000037TableGen supports BCPL (``// ...``) and nestable C-style (``/* ... */``)
38comments.
Sean Silva1b600182013-01-07 02:43:44 +000039
Renato Golin33f973a2014-04-01 09:51:49 +000040The following is a listing of the basic punctuation tokens::
Sean Silva1b600182013-01-07 02:43:44 +000041
Renato Golin33f973a2014-04-01 09:51:49 +000042 - + [ ] { } ( ) < > : ; . = ? #
Sean Silva1b600182013-01-07 02:43:44 +000043
Renato Golin33f973a2014-04-01 09:51:49 +000044Numeric literals take one of the following forms:
Sean Silva1b600182013-01-07 02:43:44 +000045
Renato Golin33f973a2014-04-01 09:51:49 +000046.. TableGen actually will lex some pretty strange sequences an interpret
47 them as numbers. What is shown here is an attempt to approximate what it
48 "should" accept.
Sean Silva1b600182013-01-07 02:43:44 +000049
Renato Golin33f973a2014-04-01 09:51:49 +000050.. productionlist::
51 TokInteger: `DecimalInteger` | `HexInteger` | `BinInteger`
52 DecimalInteger: ["+" | "-"] ("0"..."9")+
53 HexInteger: "0x" ("0"..."9" | "a"..."f" | "A"..."F")+
54 BinInteger: "0b" ("0" | "1")+
Sean Silva1b600182013-01-07 02:43:44 +000055
Renato Golin33f973a2014-04-01 09:51:49 +000056One aspect to note is that the :token:`DecimalInteger` token *includes* the
57``+`` or ``-``, as opposed to having ``+`` and ``-`` be unary operators as
58most languages do.
Sean Silva1b600182013-01-07 02:43:44 +000059
Renato Golin33f973a2014-04-01 09:51:49 +000060TableGen has identifier-like tokens:
Sean Silva1b600182013-01-07 02:43:44 +000061
Renato Golin33f973a2014-04-01 09:51:49 +000062.. productionlist::
63 ualpha: "a"..."z" | "A"..."Z" | "_"
64 TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")*
65 TokVarName: "$" `ualpha` (`ualpha` | "0"..."9")*
Sean Silva1b600182013-01-07 02:43:44 +000066
Renato Golin33f973a2014-04-01 09:51:49 +000067Note that unlike most languages, TableGen allows :token:`TokIdentifier` to
68begin with a number. In case of ambiguity, a token will be interpreted as a
69numeric literal rather than an identifier.
Sean Silva1b600182013-01-07 02:43:44 +000070
Renato Golin33f973a2014-04-01 09:51:49 +000071TableGen also has two string-like literals:
Sean Silva1b600182013-01-07 02:43:44 +000072
Renato Golin33f973a2014-04-01 09:51:49 +000073.. productionlist::
74 TokString: '"' <non-'"' characters and C-like escapes> '"'
75 TokCodeFragment: "[{" <shortest text not containing "}]"> "}]"
Sean Silva1b600182013-01-07 02:43:44 +000076
Renato Golin33f973a2014-04-01 09:51:49 +000077:token:`TokCodeFragment` is essentially a multiline string literal
78delimited by ``[{`` and ``}]``.
Sean Silvacc373352014-02-09 02:43:50 +000079
Renato Golin33f973a2014-04-01 09:51:49 +000080.. note::
81 The current implementation accepts the following C-like escapes::
Sean Silva543fd7f2013-01-09 02:20:30 +000082
Renato Golin33f973a2014-04-01 09:51:49 +000083 \\ \' \" \t \n
Sean Silva543fd7f2013-01-09 02:20:30 +000084
Renato Golin33f973a2014-04-01 09:51:49 +000085TableGen also has the following keywords::
Sean Silva1b600182013-01-07 02:43:44 +000086
Renato Golin33f973a2014-04-01 09:51:49 +000087 bit bits class code dag
88 def foreach defm field in
89 int let list multiclass string
Sean Silva1b600182013-01-07 02:43:44 +000090
Renato Golin33f973a2014-04-01 09:51:49 +000091TableGen also has "bang operators" which have a
92wide variety of meanings:
Sean Silva1b600182013-01-07 02:43:44 +000093
Renato Golin33f973a2014-04-01 09:51:49 +000094.. productionlist::
95 BangOperator: one of
96 :!eq !if !head !tail !con
97 :!add !shl !sra !srl
98 :!cast !empty !subst !foreach !strconcat
Sean Silva1b600182013-01-07 02:43:44 +000099
Renato Golin33f973a2014-04-01 09:51:49 +0000100Syntax
101======
Sean Silva1b600182013-01-07 02:43:44 +0000102
Renato Golin33f973a2014-04-01 09:51:49 +0000103TableGen has an ``include`` mechanism. It does not play a role in the
104syntax per se, since it is lexically replaced with the contents of the
105included file.
Sean Silva1b600182013-01-07 02:43:44 +0000106
Renato Golin33f973a2014-04-01 09:51:49 +0000107.. productionlist::
108 IncludeDirective: "include" `TokString`
Sean Silva1b600182013-01-07 02:43:44 +0000109
Renato Golin33f973a2014-04-01 09:51:49 +0000110TableGen's top-level production consists of "objects".
Sean Silva1b600182013-01-07 02:43:44 +0000111
Renato Golin33f973a2014-04-01 09:51:49 +0000112.. productionlist::
113 TableGenFile: `Object`*
114 Object: `Class` | `Def` | `Defm` | `Let` | `MultiClass` | `Foreach`
Sean Silva1b600182013-01-07 02:43:44 +0000115
Renato Golin33f973a2014-04-01 09:51:49 +0000116``class``\es
117------------
Sean Silva1b600182013-01-07 02:43:44 +0000118
Renato Golin33f973a2014-04-01 09:51:49 +0000119.. productionlist::
120 Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000121
Renato Golin33f973a2014-04-01 09:51:49 +0000122A ``class`` declaration creates a record which other records can inherit
123from. A class can be parametrized by a list of "template arguments", whose
124values can be used in the class body.
Sean Silva1b600182013-01-07 02:43:44 +0000125
Renato Golin33f973a2014-04-01 09:51:49 +0000126A given class can only be defined once. A ``class`` declaration is
127considered to define the class if any of the following is true:
Sean Silva1b600182013-01-07 02:43:44 +0000128
Renato Golin33f973a2014-04-01 09:51:49 +0000129.. break ObjectBody into its consituents so that they are present here?
Sean Silva1b600182013-01-07 02:43:44 +0000130
Renato Golin33f973a2014-04-01 09:51:49 +0000131#. The :token:`TemplateArgList` is present.
132#. The :token:`Body` in the :token:`ObjectBody` is present and is not empty.
133#. The :token:`BaseClassList` in the :token:`ObjectBody` is present.
Sean Silva1b600182013-01-07 02:43:44 +0000134
Renato Golin33f973a2014-04-01 09:51:49 +0000135You can declare an empty class by giving and empty :token:`TemplateArgList`
136and an empty :token:`ObjectBody`. This can serve as a restricted form of
137forward declaration: note that records deriving from the forward-declared
138class will inherit no fields from it since the record expansion is done
139when the record is parsed.
Sean Silva1b600182013-01-07 02:43:44 +0000140
Renato Golin33f973a2014-04-01 09:51:49 +0000141.. productionlist::
142 TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">"
Sean Silva1b600182013-01-07 02:43:44 +0000143
Renato Golin33f973a2014-04-01 09:51:49 +0000144Declarations
145------------
Sean Silva1b600182013-01-07 02:43:44 +0000146
Renato Golin33f973a2014-04-01 09:51:49 +0000147.. Omitting mention of arcane "field" prefix to discourage its use.
Sean Silva1b600182013-01-07 02:43:44 +0000148
Renato Golin33f973a2014-04-01 09:51:49 +0000149The declaration syntax is pretty much what you would expect as a C++
150programmer.
Sean Silva1b600182013-01-07 02:43:44 +0000151
Renato Golin33f973a2014-04-01 09:51:49 +0000152.. productionlist::
153 Declaration: `Type` `TokIdentifier` ["=" `Value`]
Sean Silva1b600182013-01-07 02:43:44 +0000154
Renato Golin33f973a2014-04-01 09:51:49 +0000155It assigns the value to the identifer.
Sean Silva1b600182013-01-07 02:43:44 +0000156
Renato Golin33f973a2014-04-01 09:51:49 +0000157Types
158-----
Sean Silva1b600182013-01-07 02:43:44 +0000159
Renato Golin33f973a2014-04-01 09:51:49 +0000160.. productionlist::
161 Type: "string" | "code" | "bit" | "int" | "dag"
162 :| "bits" "<" `TokInteger` ">"
163 :| "list" "<" `Type` ">"
164 :| `ClassID`
165 ClassID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000166
Renato Golin33f973a2014-04-01 09:51:49 +0000167Both ``string`` and ``code`` correspond to the string type; the difference
168is purely to indicate programmer intention.
Renato Golinca105642014-03-20 16:08:34 +0000169
Renato Golin33f973a2014-04-01 09:51:49 +0000170The :token:`ClassID` must identify a class that has been previously
171declared or defined.
Renato Golinca105642014-03-20 16:08:34 +0000172
Renato Golin33f973a2014-04-01 09:51:49 +0000173Values
174------
Renato Golinca105642014-03-20 16:08:34 +0000175
Renato Golin33f973a2014-04-01 09:51:49 +0000176.. productionlist::
177 Value: `SimpleValue` `ValueSuffix`*
178 ValueSuffix: "{" `RangeList` "}"
179 :| "[" `RangeList` "]"
180 :| "." `TokIdentifier`
181 RangeList: `RangePiece` ("," `RangePiece`)*
182 RangePiece: `TokInteger`
183 :| `TokInteger` "-" `TokInteger`
184 :| `TokInteger` `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000185
Renato Golin33f973a2014-04-01 09:51:49 +0000186The peculiar last form of :token:`RangePiece` is due to the fact that the
187"``-``" is included in the :token:`TokInteger`, hence ``1-5`` gets lexed as
188two consecutive :token:`TokInteger`'s, with values ``1`` and ``-5``,
189instead of "1", "-", and "5".
190The :token:`RangeList` can be thought of as specifying "list slice" in some
191contexts.
Renato Golinca105642014-03-20 16:08:34 +0000192
Renato Golinca105642014-03-20 16:08:34 +0000193
Renato Golin33f973a2014-04-01 09:51:49 +0000194:token:`SimpleValue` has a number of forms:
Renato Golinca105642014-03-20 16:08:34 +0000195
Renato Golinca105642014-03-20 16:08:34 +0000196
Renato Golin33f973a2014-04-01 09:51:49 +0000197.. productionlist::
198 SimpleValue: `TokIdentifier`
Renato Golinca105642014-03-20 16:08:34 +0000199
Renato Golin33f973a2014-04-01 09:51:49 +0000200The value will be the variable referenced by the identifier. It can be one
201of:
Renato Golinca105642014-03-20 16:08:34 +0000202
Renato Golin33f973a2014-04-01 09:51:49 +0000203.. The code for this is exceptionally abstruse. These examples are a
204 best-effort attempt.
Renato Golinca105642014-03-20 16:08:34 +0000205
Renato Golin33f973a2014-04-01 09:51:49 +0000206* name of a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000207
Renato Golin33f973a2014-04-01 09:51:49 +0000208 def Bar : SomeClass {
209 int X = 5;
210 }
Renato Golinca105642014-03-20 16:08:34 +0000211
Renato Golin33f973a2014-04-01 09:51:49 +0000212 def Foo {
213 SomeClass Baz = Bar;
214 }
Renato Golinca105642014-03-20 16:08:34 +0000215
Renato Golin33f973a2014-04-01 09:51:49 +0000216* value local to a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000217
Renato Golin33f973a2014-04-01 09:51:49 +0000218 def Foo {
219 int Bar = 5;
220 int Baz = Bar;
221 }
Renato Golinca105642014-03-20 16:08:34 +0000222
Renato Golin33f973a2014-04-01 09:51:49 +0000223* a template arg of a ``class``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000224
Renato Golin33f973a2014-04-01 09:51:49 +0000225 class Foo<int Bar> {
226 int Baz = Bar;
227 }
Renato Golinca105642014-03-20 16:08:34 +0000228
Renato Golin33f973a2014-04-01 09:51:49 +0000229* value local to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000230
Renato Golin33f973a2014-04-01 09:51:49 +0000231 multiclass Foo {
232 int Bar = 5;
233 int Baz = Bar;
234 }
Renato Golinca105642014-03-20 16:08:34 +0000235
Renato Golin33f973a2014-04-01 09:51:49 +0000236* a template arg to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000237
Renato Golin33f973a2014-04-01 09:51:49 +0000238 multiclass Foo<int Bar> {
239 int Baz = Bar;
240 }
Renato Golinca105642014-03-20 16:08:34 +0000241
Renato Golin33f973a2014-04-01 09:51:49 +0000242.. productionlist::
243 SimpleValue: `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000244
Renato Golin33f973a2014-04-01 09:51:49 +0000245This represents the numeric value of the integer.
Renato Golinca105642014-03-20 16:08:34 +0000246
Renato Golin33f973a2014-04-01 09:51:49 +0000247.. productionlist::
248 SimpleValue: `TokString`+
Renato Golinca105642014-03-20 16:08:34 +0000249
Renato Golin33f973a2014-04-01 09:51:49 +0000250Multiple adjacent string literals are concatenated like in C/C++. The value
251is the concatenation of the strings.
Renato Golinca105642014-03-20 16:08:34 +0000252
Renato Golin33f973a2014-04-01 09:51:49 +0000253.. productionlist::
254 SimpleValue: `TokCodeFragment`
Renato Golinca105642014-03-20 16:08:34 +0000255
Renato Golin33f973a2014-04-01 09:51:49 +0000256The value is the string value of the code fragment.
Renato Golinca105642014-03-20 16:08:34 +0000257
Renato Golin33f973a2014-04-01 09:51:49 +0000258.. productionlist::
259 SimpleValue: "?"
Renato Golinca105642014-03-20 16:08:34 +0000260
Renato Golin33f973a2014-04-01 09:51:49 +0000261``?`` represents an "unset" initializer.
Sean Silva1b600182013-01-07 02:43:44 +0000262
Renato Golin33f973a2014-04-01 09:51:49 +0000263.. productionlist::
264 SimpleValue: "{" `ValueList` "}"
265 ValueList: [`ValueListNE`]
266 ValueListNE: `Value` ("," `Value`)*
Sean Silva1b600182013-01-07 02:43:44 +0000267
Renato Golin33f973a2014-04-01 09:51:49 +0000268This represents a sequence of bits, as would be used to initialize a
269``bits<n>`` field (where ``n`` is the number of bits).
Sean Silva1b600182013-01-07 02:43:44 +0000270
Renato Golin33f973a2014-04-01 09:51:49 +0000271.. productionlist::
272 SimpleValue: `ClassID` "<" `ValueListNE` ">"
Sean Silva1b600182013-01-07 02:43:44 +0000273
Renato Golin33f973a2014-04-01 09:51:49 +0000274This generates a new anonymous record definition (as would be created by an
275unnamed ``def`` inheriting from the given class with the given template
276arguments) and the value is the value of that record definition.
Sean Silva1b600182013-01-07 02:43:44 +0000277
Renato Golin33f973a2014-04-01 09:51:49 +0000278.. productionlist::
279 SimpleValue: "[" `ValueList` "]" ["<" `Type` ">"]
Sean Silva1b600182013-01-07 02:43:44 +0000280
Renato Golin33f973a2014-04-01 09:51:49 +0000281A list initializer. The optional :token:`Type` can be used to indicate a
282specific element type, otherwise the element type will be deduced from the
283given values.
Sean Silva1b600182013-01-07 02:43:44 +0000284
Renato Golin33f973a2014-04-01 09:51:49 +0000285.. The initial `DagArg` of the dag must start with an identifier or
286 !cast, but this is more of an implementation detail and so for now just
287 leave it out.
Sean Silva1b600182013-01-07 02:43:44 +0000288
Renato Golin33f973a2014-04-01 09:51:49 +0000289.. productionlist::
290 SimpleValue: "(" `DagArg` `DagArgList` ")"
291 DagArgList: `DagArg` ("," `DagArg`)*
292 DagArg: `Value` [":" `TokVarName`] | `TokVarName`
Sean Silva1b600182013-01-07 02:43:44 +0000293
Renato Golin33f973a2014-04-01 09:51:49 +0000294The initial :token:`DagArg` is called the "operator" of the dag.
Sean Silva1b600182013-01-07 02:43:44 +0000295
Renato Golin33f973a2014-04-01 09:51:49 +0000296.. productionlist::
297 SimpleValue: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")"
Sean Silva1b600182013-01-07 02:43:44 +0000298
Renato Golin33f973a2014-04-01 09:51:49 +0000299Bodies
300------
Sean Silva1b600182013-01-07 02:43:44 +0000301
Renato Golin33f973a2014-04-01 09:51:49 +0000302.. productionlist::
303 ObjectBody: `BaseClassList` `Body`
304 BaseClassList: [":" `BaseClassListNE`]
305 BaseClassListNE: `SubClassRef` ("," `SubClassRef`)*
306 SubClassRef: (`ClassID` | `MultiClassID`) ["<" `ValueList` ">"]
307 DefmID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000308
Renato Golin33f973a2014-04-01 09:51:49 +0000309The version with the :token:`MultiClassID` is only valid in the
310:token:`BaseClassList` of a ``defm``.
311The :token:`MultiClassID` should be the name of a ``multiclass``.
Sean Silva1b600182013-01-07 02:43:44 +0000312
Renato Golin33f973a2014-04-01 09:51:49 +0000313.. put this somewhere else
Sean Silva1b600182013-01-07 02:43:44 +0000314
Renato Golin33f973a2014-04-01 09:51:49 +0000315It is after parsing the base class list that the "let stack" is applied.
Sean Silva1b600182013-01-07 02:43:44 +0000316
Renato Golin33f973a2014-04-01 09:51:49 +0000317.. productionlist::
318 Body: ";" | "{" BodyList "}"
319 BodyList: BodyItem*
320 BodyItem: `Declaration` ";"
321 :| "let" `TokIdentifier` [`RangeList`] "=" `Value` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000322
Renato Golin33f973a2014-04-01 09:51:49 +0000323The ``let`` form allows overriding the value of an inherited field.
Sean Silva1b600182013-01-07 02:43:44 +0000324
Renato Golin33f973a2014-04-01 09:51:49 +0000325``def``
326-------
Sean Silva1b600182013-01-07 02:43:44 +0000327
Renato Golin33f973a2014-04-01 09:51:49 +0000328.. TODO::
329 There can be pastes in the names here, like ``#NAME#``. Look into that
330 and document it (it boils down to ParseIDValue with IDParseMode ==
331 ParseNameMode). ParseObjectName calls into the general ParseValue, with
332 the only different from "arbitrary expression parsing" being IDParseMode
333 == Mode.
Sean Silva1b600182013-01-07 02:43:44 +0000334
Renato Golin33f973a2014-04-01 09:51:49 +0000335.. productionlist::
336 Def: "def" `TokIdentifier` `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000337
Renato Golin33f973a2014-04-01 09:51:49 +0000338Defines a record whose name is given by the :token:`TokIdentifier`. The
339fields of the record are inherited from the base classes and defined in the
340body.
Sean Silva1b600182013-01-07 02:43:44 +0000341
Renato Golin33f973a2014-04-01 09:51:49 +0000342Special handling occurs if this ``def`` appears inside a ``multiclass`` or
343a ``foreach``.
Sean Silva1b600182013-01-07 02:43:44 +0000344
Renato Golin33f973a2014-04-01 09:51:49 +0000345``defm``
346--------
Sean Silva1b600182013-01-07 02:43:44 +0000347
Renato Golin33f973a2014-04-01 09:51:49 +0000348.. productionlist::
349 Defm: "defm" `TokIdentifier` ":" `BaseClassListNE` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000350
Renato Golin33f973a2014-04-01 09:51:49 +0000351Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must
352precede any ``class``'s that appear.
Sean Silva1b600182013-01-07 02:43:44 +0000353
Renato Golin33f973a2014-04-01 09:51:49 +0000354``foreach``
355-----------
Sean Silva1b600182013-01-07 02:43:44 +0000356
Renato Golin33f973a2014-04-01 09:51:49 +0000357.. productionlist::
358 Foreach: "foreach" `Declaration` "in" "{" `Object`* "}"
359 :| "foreach" `Declaration` "in" `Object`
Sean Silva1b600182013-01-07 02:43:44 +0000360
Renato Golin33f973a2014-04-01 09:51:49 +0000361The value assigned to the variable in the declaration is iterated over and
362the object or object list is reevaluated with the variable set at each
363iterated value.
Sean Silva1b600182013-01-07 02:43:44 +0000364
Renato Golin33f973a2014-04-01 09:51:49 +0000365Top-Level ``let``
366-----------------
Sean Silva1b600182013-01-07 02:43:44 +0000367
Renato Golin33f973a2014-04-01 09:51:49 +0000368.. productionlist::
369 Let: "let" `LetList` "in" "{" `Object`* "}"
370 :| "let" `LetList` "in" `Object`
371 LetList: `LetItem` ("," `LetItem`)*
372 LetItem: `TokIdentifier` [`RangeList`] "=" `Value`
Sean Silva1b600182013-01-07 02:43:44 +0000373
Renato Golin33f973a2014-04-01 09:51:49 +0000374This is effectively equivalent to ``let`` inside the body of a record
375except that it applies to multiple records at a time. The bindings are
376applied at the end of parsing the base classes of a record.
Sean Silva1b600182013-01-07 02:43:44 +0000377
Renato Golin33f973a2014-04-01 09:51:49 +0000378``multiclass``
379--------------
Sean Silva1b600182013-01-07 02:43:44 +0000380
Renato Golin33f973a2014-04-01 09:51:49 +0000381.. productionlist::
382 MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`]
383 : [":" `BaseMultiClassList`] "{" `MultiClassObject`+ "}"
384 BaseMultiClassList: `MultiClassID` ("," `MultiClassID`)*
385 MultiClassID: `TokIdentifier`
386 MultiClassObject: `Def` | `Defm` | `Let` | `Foreach`