chiark / gitweb /
src/c-types-*.lisp: New type for functions which take keyword arguments.
[sod] / doc / clang.tex
index 52e330de1c184ae5f39a763045035f1d42a097bb..6f7e218d2abb09478fe0291ebf82c9b0065d4cd3 100644 (file)
@@ -7,7 +7,7 @@
 
 %%%----- Licensing notice ---------------------------------------------------
 %%%
-%%% This file is part of the Sensble Object Design, an object system for C.
+%%% This file is part of the Sensible Object Design, an object system for C.
 %%%
 %%% SOD is free software; you can redistribute it and/or modify
 %%% it under the terms of the GNU General Public License as published by
@@ -48,7 +48,8 @@ The class hierarchy is shown in~\xref{fig:codegen.c-types.classes}.
           @|c-enum-type| \- \\
         @|c-pointer-type| \- \\
       @|c-array-type| \\
-      @|c-function-type|
+      @|c-function-type| \\ \ind
+        @|c-keyword-function-type| \-
   \end{tabbing}}
   \caption{Classes representing C types}
 \label{fig:codegen.c-types.classes}
@@ -65,11 +66,12 @@ specified to return interned objects: programs may rely on receiving the same
 (@|eq|) type object for similar (possibly merely @|equal|) arguments.  Where
 not specified, clients may still not rely on receiving fresh objects.
 
-A convenient S-expression notation is provided by the @|c-type| macro.  Use
-of this macro is merely an abbreviation for corresponding use of the various
-constructor functions, and therefore interns type objects in the same manner.
-The syntax accepted by the macro can be extended in order to support new
-classes: see @|defctype|, @|c-type-alias| and @|define-c-type-syntax|.
+A convenient S-expression notation is provided by the
+\descref{c-type}[macro]{mac}.  Use of this macro is merely an abbreviation
+for corresponding use of the various constructor functions, and therefore
+interns type objects in the same manner.  The syntax accepted by the macro
+can be extended in order to support new classes: see \descref{defctype}{mac},
+\descref{c-type-alias}{mac} and \descref{define-c-type-syntax}{mac}.
 
 The descriptions of each of the various classes include descriptions of the
 initargs which may be passed to @|make-instance| when constructing a new
@@ -80,14 +82,15 @@ syntax are strongly recommended over direct use of @|make-instance|.
 There are two protocols for printing C types.  Unfortunately they have
 similar names.
 \begin{itemize}
-\item The @|print-c-type| function prints a C type value using the
-  S-expression notation.  It is mainly useful for diagnostic purposes.
-\item The @|pprint-c-type| function prints a C type as a C-syntax
-  declaration.
+\item The \descref{print-c-type}[function]{gf} prints a C type value using
+  the S-expression notation.  It is mainly useful for diagnostic purposes.
+\item The \descref{pprint-c-type}[function]{gf} prints a C type as a
+  C-syntax declaration.
 \end{itemize}
 Neither generic function defines a default primary method; subclasses of
 @|c-type| must define their own methods in order to print correctly.
 
+
 \subsection{The C type root class} \label{sec:clang.c-types.root}
 
 \begin{describe}{cls}{c-type ()}
@@ -100,6 +103,7 @@ Neither generic function defines a default primary method; subclasses of
   The class @|c-type| is abstract.
 \end{describe}
 
+
 \subsection{C type S-expression notation} \label{sec:clang.c-types.sexp}
 
 The S-expression representation of a type is described syntactically as a
@@ -120,8 +124,9 @@ type specifier.  Type specifiers fit into two syntactic categories.
 \end{describe}
 
 \begin{describe}{mac}
-    {defctype @{ @<name> @! (@<name> @<nickname>^*) @} @<type-spec>
-      @> @<names>}
+    {defctype \=@{ @<name> @! (@<name>^+) @} @<type-spec> \+ \\
+                @[[ @|:export| @<export-flag> @]]^* \-
+       \nlret @<names>}
   Defines a new symbolic type specifier @<name>; if a list of @<name>s is
   given, then all are defined in the same way.  The type constructed by using
   any of the @<name>s is as described by the type specifier @<type-spec>.
@@ -129,6 +134,13 @@ type specifier.  Type specifiers fit into two syntactic categories.
   The resulting type object is constructed once, at the time that the macro
   expansion is evaluated; the same (@|eq|) value is used each time any
   @<name> is used in a type specifier.
+
+  A variable named @|c-type-@<name>|, for the first @<name> only, is defined
+  and initialized to contain the C type object so constructed.  Altering or
+  binding this name is discouraged.
+
+  If @<export-flag> is true, then the variable name, and all of the @<name>s,
+  are exported from the current package.
 \end{describe}
 
 \begin{describe}{mac}{c-type-alias @<original> @<alias>^* @> @<aliases>}
@@ -138,7 +150,10 @@ type specifier.  Type specifiers fit into two syntactic categories.
 \end{describe}
 
 \begin{describe}{mac}
-    {define-c-type-syntax @<name> @<lambda-list> @<form>^* @> @<name>}
+    {define-c-type-syntax @<name> @<lambda-list> \\ \ind
+      @[[ @<declaration>^* @! @<doc-string> @]] \\
+      @<form>^* \-
+     \nlret @<name>}
   Defines the symbol @<name> as a new type operator.  When a list of the form
   @|(@<name> @<argument>^*)| is used as a type specifier, the @<argument>s
   are bound to fresh variables according to @<lambda-list> (a destructuring
@@ -166,6 +181,7 @@ type specifier.  Type specifiers fit into two syntactic categories.
   default method.
 \end{describe}
 
+
 \subsection{Comparing C types} \label{sec:clang.c-types.cmp}
 
 It is necessary to compare C types for equality, for example when checking
@@ -196,6 +212,7 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   \end{describe}
 \end{describe}
 
+
 \subsection{Outputting C types} \label{sec:clang.c-types.output}
 
 \begin{describe}{gf}{pprint-c-type @<c-type> @<stream> @<kernel>}
@@ -232,15 +249,14 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   directly attached.  If the @<kernel> function intends to provide its own
   additional declarator operators, it should check the @<priority> in order
   to determine whether parentheses are necessary.  See also the
-  @|maybe-in-parens| macro (page~\pageref{mac:maybe-in-parens}).
+  \descref{maybe-in-parens}[macro]{mac}.
 
   The @<spacep> argument indicates whether a space needs to be printed in
   order to separate the declarator from the declaration specifiers.  A kernel
   which contains an identifier should insert a space before the identifier
   when @<spacep> is non-nil.  An `empty' kernel, as found in an abstract
   declarator (one that specifies no name), looks more pleasing without a
-  trailing space.  See also the @|c-type-space| function
-  (page~\pageref{fun:c-type-space}).
+  trailing space.  See also the \descref{c-type-space}[function]{fun}.
 
   Every concrete subclass of @|c-type| is expected to provide a primary
   method on this function.  There is no default primary method.
@@ -265,7 +281,9 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
 \end{describe}
 
 \begin{describe}{mac}
-    {maybe-in-parens (@<stream-var> @<guard-form>) @<form>^*}
+    {maybe-in-parens (@<stream-var> @<guard-form>)
+      @<declaration>^*
+      @<form>^*}
   The @<guard-form> is evaluated, and then the @<form>s are evaluated in
   sequence within a pretty-printer logical block writing to the stream named
   by the symbol @<stream-var>.  If the @<guard-form> evaluates to nil, then
@@ -277,6 +295,7 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   within the @<form>s.
 \end{describe}
 
+
 \subsection{Type qualifiers and qualifiable types}
 \label{sec:clang.ctypes.qual}
 
@@ -290,8 +309,8 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   qualifiers; others keywords may be used, though this isn't recommended.
 
   Two qualifiable types are equal only if they have \emph{matching
-    qualifiers}: i.e., every qualifier attached to one is also attached to
-  the other: order is not significant, and neither is multiplicity.
+  qualifiers}: i.e., every qualifier attached to one is also attached to the
+  other: order is not significant, and neither is multiplicity.
 
   The class @|qualifiable-c-type| is abstract.
 \end{describe}
@@ -311,12 +330,13 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   type will be interned.
 \end{describe}
 
-\begin{describe}{fun}{format-qualifiers @<qualifiers>}
+\begin{describe}{fun}{format-qualifiers @<qualifiers> @> @<string>}
   Returns a string containing the qualifiers listed in @<qualifiers> in C
   syntax, with a space after each.  In particular, if @<qualifiers> is
   non-null then the final character of the returned string will be a space.
 \end{describe}
 
+
 \subsection{Leaf types} \label{sec:clang.c-types.leaf}
 
 A \emph{leaf type} is a type which is not defined in terms of another type.
@@ -350,9 +370,11 @@ In Sod, the leaf types are
   \begin{tabular}[C]{ll}                                           \hlx*{hv}
     \thd{C type}        & \thd{Specifiers}                      \\ \hlx{vhv}
     @|void|             & @|void|                               \\ \hlx{v}
-    @|char|             & @|char|                               \\ \hlx{v}
-    @|unsigned char|    & @|unsigned-char|, @|uchar|            \\ \hlx{}
-    @|signed char|      & @|signed-char|, @|schar|              \\ \hlx{v}
+    @|_Bool|            & @|bool|                               \\ \hlx{v}
+    @|char|             & @|char|                               \\ \hlx{}
+    @|wchar_t|          & @|wchar-t|                            \\ \hlx{v}
+    @|signed char|      & @|signed-char|, @|schar|              \\ \hlx{}
+    @|unsigned char|    & @|unsigned-char|, @|uchar|            \\ \hlx{v}
     @|short|            & @|short|, @|signed-short|, @|short-int|,
                           @|signed-short-int| @|sshort|         \\ \hlx{}
     @|unsigned short|   & @|unsigned-short|, @|unsigned-short-int|,
@@ -365,17 +387,26 @@ In Sod, the leaf types are
     @|unsigned long|    & @|unsigned-long|, @|unsigned-long-int|,
                           @|ulong|                              \\ \hlx{v}
     @|long long|        & @|long-long|, @|signed-long-long|,
-                          @|long-long-int|,                     \\
+                          @|long-long-int|,                     \\ \hlx{}
                         & \qquad @|signed-long-long-int|,
                           @|llong|, @|sllong|                   \\ \hlx{v}
     @|unsigned long long|
                         & @|unsigned-long-long|, @|unsigned-long-long-int|,
                           @|ullong|                             \\ \hlx{v}
+    @|size_t|           & @|size-t|                             \\ \hlx{}
+    @|ptrdiff_t|        & @|ptrdiff-t|                          \\ \hlx{v}
     @|float|            & @|float|                              \\ \hlx{}
-    @|double|           & @|double|                             \\ \hlx{v}
-    @|va_list|          & @|va-list|                            \\ \hlx{v}
-    @|size_t|           & @|size-t|                             \\ \hlx{v}
-    @|ptrdiff_t|        & @|ptrdiff-t|                          \\ \hlx*{vh}
+    @|double|           & @|double|                             \\ \hlx{}
+    @|long double|      & @|long-double|                        \\ \hlx{v}
+    @|float _Imaginary| & @|float-imaginary|                    \\ \hlx{}
+    @|double _Imaginary|& @|double-imaginary|                   \\ \hlx{}
+    @|long double _Imaginary|
+                        & @|long-double-imaginary|              \\ \hlx{v}
+    @|float _Complex|   & @|float-complex|                      \\ \hlx{}
+    @|double _Complex|  & @|double-complex|                     \\ \hlx{}
+    @|long double _Complex|
+                        & @|long-double-complex|                \\ \hlx{v}
+    @|va_list|          & @|va-list|                            \\ \hlx*{vh}
   \end{tabular}
   \caption{Builtin symbolic type specifiers for simple C types}
   \label{tab:codegen.c-types.simple}
@@ -394,13 +425,21 @@ In Sod, the leaf types are
 \end{describe}
 
 \begin{describe}{mac}
-    {define-simple-c-type @{ @<name> @! (@<name>^*) @} @<string> @> @<name>}
+    {define-simple-c-type \=@{ @<name> @! (@<name>^+) @} @<string> \+ \\
+                            @[[ @|:export| @<export-flag> @]] \-
+      \nlret @<name>}
   Define type specifiers for a new simple C type.  Each symbol @<name> is
   defined as a symbolic type specifier for the (unique interned) simple C
   type whose name is the value of @<string>.  Further, each @<name> is
   defined to be a type operator: the type specifier @|(@<name>
   @<qualifier>^*)| evaluates to the (unique interned) simple C type whose
   name is @<string> and which has the @<qualifiers> (which are evaluated).
+
+  Furthermore, a variable @|c-type-@<name>| is defined, for the first @<name>
+  only, and initialized with the newly constructed C type object.
+
+  If @<export-flag> is true, then the @|c-type-@<name>| variable name, and
+  all of the @<name>s, are exported from the current package.
 \end{describe}
 
 \begin{describe}{cls}{tagged-c-type (qualifiable-c-type)
@@ -483,6 +522,7 @@ In Sod, the leaf types are
   keywords).
 \end{describe}
 
+
 \subsection{Compound C types} \label{sec:code.c-types.compound}
 
 Some C types are \emph{compound types}: they're defined in terms of existing
@@ -494,10 +534,11 @@ protocol.
   this means depends on the class of @<c-type>.
 \end{describe}
 
+
 \subsection{Pointer types} \label{sec:clang.c-types.pointer}
 
-Pointers compound types.  The subtype of a pointer type is the type it points
-to.
+Pointers are compound types.  The subtype of a pointer type is the type it
+points to.
 
 \begin{describe}{cls}
     {c-pointer-type (qualifiable-c-type) \&key :qualifiers :subtype}
@@ -526,6 +567,7 @@ to.
   interned also.
 \end{describe}
 
+
 \subsection{Array types} \label{sec:clang.c-types.array}
 
 Arrays implement the compound-type protocol.  The subtype of an array type is
@@ -567,6 +609,7 @@ the array element type.
   Returns the dimensions of @<c-type>, an array type, as an immutable list.
 \end{describe}
 
+
 \subsection{Function types} \label{sec:clang.c-types.fun}
 
 Function types implement the compound-type protocol.  The subtype of a
@@ -581,7 +624,8 @@ function type is the type of the function's return value.
   not return nil.
 \end{describe}
 
-\begin{describe}{fun}{make-argument @<name> @<c-type> @> @<argument>}
+\begin{describe}{fun}
+    {make-argument @<name> @<c-type> \&optional @<default> @> @<argument>}
   Construct and a return a new @<argument> object.  The argument has type
   @<c-type>, which must be a @|c-type| object, and is named @<name>.
 
@@ -590,15 +634,22 @@ function type is the type of the function's return value.
   suitable for function definitions.  If @<name> is not nil, then the
   @<name>'s print representation, with @|*print-escape*| nil, is used as the
   argument name.
-\end{describe}
 
-\begin{describe}{fun}{argument-name @<argument> @> @<name>}
-  Return the name of the @<argument>, as it was supplied to @|make-argument|.
+  A @<default> may be supplied.  If the argument is used in a
+  keyword-argument list (e.g., in a \descref{c-keyword-function-type}
+  [object]{cls}), and the @<default> value is provided and non-nil, then its
+  (unescaped) printed representation is used to provide a default value if
+  the keyword argument is not supplied by the caller.
 \end{describe}
 
-\begin{describe}{fun}{argument-type @<argument> @> @<c-type>}
-  Return the type of the @<argument>, as it was supplied to @|make-argument|.
-\end{describe}
+\begin{describe*}
+    {\dhead{fun}{argument-name @<argument> @> @<name>}
+     \dhead{fun}{argument-type @<argument> @> @<c-type>}
+     \dhead{fun}{argument-default @<argument> @> @<default>}}
+  Accessor functions for @|argument| objects.  They return the appropriate
+  component of the object, as set by to @|make-argument|.  The @<default> is
+  nil if no default was provided to @|make-argument|.
+\end{describe*}
 
 \begin{describe}{gf}
     {commentify-argument-name @<name> @> @<commentified-name>}
@@ -652,14 +703,19 @@ function type is the type of the function's return value.
   in the same order, and either both or neither argument list ends with
   @|:ellipsis|; argument names are not compared.
 
-  The type specifier @|(fun @<return-type> @{ (@<arg-name> @<arg-type>) @}^*
-  @[:ellipsis @! . @<form> @])| constructs a function type.  The function has
-  the subtype @<return-type>.  The remaining items in the type-specifier list
-  are used to construct the argument list.  The argument items are a possibly
-  improper list, beginning with zero or more \emph{explicit arguments}:
-  two-item @<arg-name>/@<arg-type> lists.  For each such list, an @|argument|
-  object is constructed with the given name (evaluated) and type.  Following
-  the explicit arguments, there may be
+  The type specifier
+  \begin{prog}
+    (fun @<return-type>
+         @{ (@<arg-name> @<arg-type>) @}^*
+         @[:ellipsis @! . @<form>@])
+  \end{prog}
+  constructs a function type.  The function has the subtype @<return-type>.
+  The remaining items in the type-specifier list are used to construct the
+  argument list.  The argument items are a possibly improper list, beginning
+  with zero or more \emph{explicit arguments}: two-item
+  @<arg-name>/@<arg-type> lists.  For each such list, an @|argument| object
+  is constructed with the given name (evaluated) and type.  Following the
+  explicit arguments, there may be
   \begin{itemize}
   \item nothing, in which case the function's argument list consists only of
     the explicit arguments;
@@ -689,10 +745,72 @@ function type is the type of the function's return value.
   \end{prog}
 \end{describe}
 
+\begin{describe}{cls}
+    {c-keyword-function-type (c-function-type)
+      \&key :subtype :arguments :keywords}
+  Represents `functions' which accept keyword arguments.  Of course, actual C
+  functions can't accept keyword arguments directly, but this type is useful
+  for describing messages and methods which deal with keyword arguments.
+
+  An instance denotes the type of C function which accepts the position
+  argument list @<arguments>, and keyword arguments from the @<keywords>
+  list, and returns @<subtype>.  Either or both of the @<arguments> and
+  @<keywords> lists may be empty.  (It is important to note the distinction
+  between a function which doesn't accept keyword arguments, and one which
+  does but for which no keyword arguments are defined.  In particular, the
+  latter function can be changed later to accept a keyword argument without
+  breaking compatibility with old code.)  The @<arguments> and @<keywords>
+  lists must \emph{not} contain @|:ellipsis| markers: a function can accept
+  keywords, or a variable-length argument tail, but not both.
+
+  Keyword arguments may (but need not) have a \emph{default value} which is
+  supplied to the function body if the keyword is omitted.
+
+  Keyword functions are never considered to be the same as ordinary
+  functions.  Two keyword function types are considered to be the same if
+  their return types are the same, and their positional argument lists consist of
+  arguments with the same type, in the same order: the keyword arguments
+  accepted by the functions is not significant.
+
+  Keyword functions are constructed using an extended version of the @|fun|
+  specifier used for ordinary C function types.  The extended syntax is as
+  follows.
+  \begin{prog}
+    (fun \=@<return-type>
+           @{ (@<arg-name> @<arg-type>) @}^* \+ \\
+           @{ \=:keys @{ (@<kw-name> @<kw-type> @[@<kw-default>@]) @}^*
+                   @[. @<form>@] @! \+ \\
+                 . @<form> @}
+  \end{prog}
+  where either the symbol @|:keys| appears literally in the specifier, or the
+  @<form> evaluates to a list containing the symbol @|:keys|.  (If neither of
+  these circumstances obtains, then the specifier constructs an ordinary
+  function type.)
+
+  See the description of \descref{c-function-type}{cls} for how a trailing
+  @<form> is handled.
+
+  The list of @<arg-name>s and @<arg-type>s describes the positional
+  arguments.  The list of @<kw-name>s, @<kw-type>s and @<kw-defaults>s
+  describes the keyword arguments.
+\end{describe}
+
 \begin{describe}{fun}
     {make-function-type @<subtype> @<arguments> @> @<c-function-type>}
   Construct and return a new function type, returning @<subtype> and
   accepting the @<arguments>.
+
+  If the @<arguments> list contains a @|:keys| marker, then a
+  \descref{c-keyword-function-type}[object]{cls} is returned: those arguments
+  preceding the @|:keys| marker form the positional argument list, and those
+  following the marker form the list of keyword arguments.
+\end{describe}
+
+\begin{describe}{fun}
+    {make-keyword-function-type @<subtype> @<arguments> @<keywords>
+      \nlret @<c-keyword-function-type>}
+  Construct and return a new keyword-function type, returning @<subtype> and
+  accepting the @<arguments> and @<keywords>.
 \end{describe}
 
 \begin{describe}{gf}
@@ -709,14 +827,111 @@ function type is the type of the function's return value.
   @|commentify-argument-names| to the argument list of the given type.
 \end{describe}
 
+\begin{describe}{fun}{reify-variable-argument-tail @<arguments> @> @<list>}
+  If the @<argument> list contains an @|:ellipsis| marker, then replace it
+  with a @|va_list|.  The name for the new argument, if any, is taken from
+  the \descref{*sod-ap*}[variable]{var}.  The new list is returned; the
+  original list is not modified, but may share structure with the new list.
+\end{describe}
+
+\begin{describe}{fun}{merge-keyword-lists @<lists> @> @<list>}
+  Merge a number of keyword-argument lists together and return the result.
+
+  The @<lists> parameter is a list consisting of a number of @|(@<args>
+  . @<origin>)| pairs: in each pair, @<args> is a list of
+  \descref{argument}{cls} objects, and @<origin> is either nil or an object
+  whose printed representation describes the origin of the corresponding
+  @<args> list, suitable for inclusion in an error message.
+
+  The resulting list contains exactly one argument for each distinct argument
+  name appearing in the input @<lists>; this argument will contain the
+  default value from the earliest occurrence in the input @<lists> of an
+  argument with that name.
+
+  If the same name appears multiple times with different types, an error is
+  signalled quoting the name, conflicting types, and (if non-nil) the origins
+  of the offending argument objects.
+\end{describe}
+
+\begin{describe}{fun}
+    {pprint-c-function-type @<return-type> @<stream>
+                            @<print-args> @<print-kernel>}
+  Provides the top-level structure for printing C function types.
+
+  Output is written to @<stream> to describe a function type returning
+  @<return-type>, whose declarator kernel (containing the name, and any
+  further type operands) will be printed by @<print-kernel>, and whose
+  arguments, if any, will be printed by @<print-args>.
+
+  The @<print-kernel> function is a standard kernel-printing function
+  following the \descref{pprint-c-type}[protocol]{gf}.
+
+  The @<print-args> function is given a single argument, which is the
+  @<stream> to print on.  It should not print the surrounding parentheses.
+
+  The output written to @<stream> looks approximately like
+  \begin{prog}
+    @<return-type> @<kernel>(@<args>)
+  \end{prog}
+\end{describe}
+
+\begin{describe}{fun}{pprint-argument-list @<args> @<stream> @> @<flag>}
+  Print an argument list to @<stream>.
+
+  The @<args> is a list of \descref{argument}[objects]{cls}, optionally
+  containing an @|:ellipsis| marker.  The function returns true if any
+  arguments were actually printed.
+\end{describe}
+
+
 \subsection{Parsing C types} \label{sec:clang.c-types.parsing}
 
+\begin{describe}{fun}
+    {parse-c-type @<scanner>
+      @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{fun}
+    {parse-declarator @<scanner> @<base-type> \&key :kernel :abstractp
+      \nlret @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+
+\subsection{Class types} \label{sec:clang.c-types.class}
+
+\begin{describe}{cls}
+    {c-class-type (simple-c-type) \&key :class :tag :qualifiers :name}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{gf}{c-type-class @<class-type> @> @<class>}
+     \dhead{gf}{setf (c-type-class @<class-type>) @<class>}}
+\end{describe*}
+
+\begin{describe}{fun}{find-class-type @<name> @> @<class-type-or-nil>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-class-type @<name> \&optional @<qualifiers> @> @<class-type>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-class-type @<name> \&optional @<qualifiers> @> @<class-type>}
+\end{describe}
+
+\begin{describe}{fun}{find-sod-class @<name> @> @<class>}
+\end{describe}
+
+\begin{describe}{fun}{record-sod-class @<class>}
+\end{describe}
+
 %%%--------------------------------------------------------------------------
 \section{Generating C code} \label{sec:clang.codegen}
 
 This section deals with Sod's facilities for constructing and manipulating C
 expressions, declarations, instructions and definitions.
 
+
 \subsection{Temporary names} \label{sec:clang.codegen.temporaries}
 
 Many C-level objects, especially ones with external linkage or inclusion in a
@@ -785,12 +1000,13 @@ Temporary names are represented by objects which implement a simple protocol.
     \thd{\textbf{Variable}} & \thd{\textbf{Name format}}        \\ \hlx{vhv}
     {}*sod-ap*                  & sod__ap                       \\
     {}*sod-master-ap*           & sod__master_ap                \\
-    {}*sod-tmp-ap*              & sod__tmp_ap                   \\ \hlx*{vh}
+    {}*null-pointer*            & NULL                          \\ \hlx*{vh}
   \end{tabular}
   \caption{Well-known temporary names}
   \label{tab:codegen.codegen.well-known-temps}
 \end{table}
 
+
 \subsection{Instructions} \label{sec:clang.codegen.insts}
 
 \begin{describe}{cls}{inst () \&key}
@@ -800,13 +1016,21 @@ Temporary names are represented by objects which implement a simple protocol.
 \end{describe}
 
 \begin{describe}{mac}
-    {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*)
-      @<body-form>^*}
+    {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*) \\ \ind
+      @[[ @<declaration>^* @! @<doc-string> @]] \\
+      @<form>^* \-
+     \nlret @<code>}
 \end{describe}
 
 \begin{describe}{mac}
-    {format-compound-statement (@<stream> @<child> \&optional @<morep>)
-      @<body-form>^*}
+    {format-compound-statement
+        (@<stream> @<child> \&optional @<morep>) \\ \ind
+      @<declaration>^* \\
+      @<form>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {format-banner-comment @<stream> @<control> \&rest @<args>}
 \end{describe}
 
 \begin{table}
@@ -814,41 +1038,50 @@ Temporary names are represented by objects which implement a simple protocol.
     \thd{Class name} &
     \thd{Arguments} &
     \thd{Output format}                                         \\ \hlx{vhv}
-    @|var|      & @<name> @<type> @<init>  & @<type> @<name> @[= @<init>@];
+    @|var|      & @<name> @<type> @|\&optional| @<init>
+                                           & @<type> @<name> @[= @<init>@];
                                                                 \\ \hlx{v}
     @|set|      & @<var> @<expr>           & @<var> = @<expr>;  \\ \hlx{v}
     @|update|   & @<var> @<op> @<expr>     & @<var> @<op>= @<expr>;
                                                                 \\ \hlx{v}
+    @|cond|     & @<cond> @<conseq> @<alt> & @<cond> ? @<conseq> : @<alt>
+                                                                \\ \hlx{v}
     @|return|   & @<expr>                  & return @[@<expr>@];
                                                                 \\ \hlx{v}
     @|break|    & ---                      & break;             \\ \hlx{v}
     @|continue| & ---                      & continue;          \\ \hlx{v}
     @|expr|     & @<expr>                  & @<expr>;           \\ \hlx{v}
-    @|call|     & @<func> @<args>          & @<func>(@<arg>_1,
+    @|call|     & @<func> @|\&rest| @<args>
+                                           & @<func>(@<arg>_1,
                                                      $\ldots$,
                                                      @<arg>_n)  \\ \hlx{v}
-    @|va-start| & @<ap> @<arg>             & va_start(@<ap>, @<arg>);
-                                                                \\ \hlx{v}
-    @|va-copy|  & @<to> @<from>            & va_copy(@<to>, @<from>);
-                                                                \\ \hlx{v}
-    @|va-end|   & @<ap>                    & va_end(@<ap>);     \\ \hlx{vhv}
+    @|banner|   & @<control> @|\&rest| @<args>
+                                           & /* @<banner> */    \\ \hlx{vhv}
     @|block|    & @<decls> @<body>         & \{ @[@<decls>@] @<body> \}
                                                                 \\ \hlx{v}
-    @|if|       & @<cond> @<conseq> @<alt> & if (@<cond>) @<conseq>
+    @|if|       & @<cond> @<conseq> @|\&optional| @<alt>
+                                           & if (@<cond>) @<conseq>
                                              @[else @<alt>@]    \\ \hlx{v}
+    @|for|      & @<init> @<cond> @<update> @<body> &
+      for (@<init>; @<cond>; @<update>) @<body>                 \\ \hlx{v}
     @|while|    & @<cond> @<body>          & while (@<cond>) @<body>
                                                                 \\ \hlx{v}
     @|do-while| & @<body> @<cond>          & do @<body> while (@<cond>);
                                                                 \\ \hlx{v}
-    @|function| & @<name> @<type> @<body>  &
-      @<type>_0 @<name>(@<type>_1 @<arg>_1, $\ldots$,
-                             @<type>_n @<arg>_n @[, \dots@])
-        @<body>                                                 \\ \hlx*{vh}
+    @|function| &
+      \vtop{\hbox{\strut @<name> @<type> @<body>}
+            \hbox{\strut \quad @|\&optional @<banner>|}
+            \hbox{\strut \quad @|\&rest| @<banner-args>}} &
+      \vtop{\hbox{\strut @[/* @<banner> */@]}
+            \hbox{\strut @<type>_0 @<name>(@<type>_1 @<arg>_1, $\ldots$,
+                                           @<type>_n @<arg>_n @[, \dots@])}
+            \hbox{\strut \quad @<body>}}                        \\ \hlx*{vh}
   \end{tabular}
   \caption{Instruction classes}
   \label{tab:codegen.codegen.insts}
 \end{table}
 
+
 \subsection{Code generation} \label{sec:clang.codegen.codegen}
 
 \begin{describe}{gf}{codegen-functions @<codegen> @> @<list>}
@@ -867,7 +1100,10 @@ Temporary names are represented by objects which implement a simple protocol.
 \begin{describe}{gf}{emit-decl @<codegen> @<decl>}
 \end{describe}
 
-\begin{describe}{gf}{emit-declss @<codegen> @<decls>}
+\begin{describe}{gf}{emit-decls @<codegen> @<decls>}
+\end{describe}
+
+\begin{describe}{fun}{emit-banner @<codegen> @<control> \&rest @<args>}
 \end{describe}
 
 \begin{describe}{gf}{codegen-push @<codegen>}
@@ -895,13 +1131,19 @@ Temporary names are represented by objects which implement a simple protocol.
 \end{describe}
 
 \begin{describe}{mac}
-    {with-temporary-var (@<codegen> @<var> @<type>) @<body-form>^*
-      @> @<value>^*}
+    {with-temporary-var (@<codegen> @<var> @<type>) \\ \ind
+      @<declaration>^* \\
+      @<form>^* \-
+     \nlret @<value>^*}
 \end{describe}
 
 \begin{describe}{fun}{deliver-expr @<codegen> @<target> @<expr>}
 \end{describe}
 
+\begin{describe}{fun}
+    {deliver-call @<codegen> @<target> @<func> \&rest @<args>}
+\end{describe}
+
 \begin{describe}{fun}{convert-stmts @<codegen> @<target> @<type> @<func>}
 \end{describe}
 
@@ -927,7 +1169,6 @@ Temporary names are represented by objects which implement a simple protocol.
       \nlret @<result> @<success-flag> @<consumed-flag>}
 \end{describe}
 
-\relax
 %%%----- That's all, folks --------------------------------------------------
 
 %%% Local variables: