@@@ mess!
[sod] / doc / clang.tex
index 38e4b20..de9e8df 100644 (file)
@@ -38,20 +38,22 @@ The class hierarchy is shown in~\xref{fig:codegen.c-types.classes}.
 
 \begin{figure} \centering
   \parbox{10pt}{\begin{tabbing}
-    @|c-type| \\ \ind
-      @|qualifiable-c-type| \\ \ind
-        @|simple-c-type| \\ \ind
-          @|c-class-type| \- \\
-        @|tagged-c-type| \\ \ind
-          @|c-struct-type| \\
-          @|c-union-type| \\
-          @|c-enum-type| \- \\
-        @|c-pointer-type| \- \\
-      @|c-array-type| \\
-      @|c-function-type|
+    @|c-type|                                                   \\ \ind
+      @|qualifiable-c-type|                                     \\ \ind
+        @|simple-c-type|                                        \\ \ind
+          @|c-class-type|                                     \-\\
+        @|tagged-c-type|                                        \\ \ind
+          @|c-struct-type|                                      \\
+          @|c-union-type|                                       \\
+          @|c-enum-type|                                      \-\\
+        @|c-atomic-type|                                        \\
+        @|c-pointer-type|                                     \-\\
+      @|c-array-type|                                           \\
+      @|c-function-type|                                        \\ \ind
+        @|c-keyword-function-type|                            \-
   \end{tabbing}}
   \caption{Classes representing C types}
-\label{fig:codegen.c-types.classes}
+  \label{fig:codegen.c-types.classes}
 \end{figure}
 
 C type objects are immutable unless otherwise specified.
@@ -66,11 +68,11 @@ specified to return interned objects: programs may rely on receiving the same
 not specified, clients may still not rely on receiving fresh objects.
 
 A convenient S-expression notation is provided by the
-\descref{c-type}[macro]{mac}.  Use of this macro is merely an abbreviation
+\descref{mac}{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 \descref{defctype}{mac},
-\descref{c-type-alias}{mac} and \descref{define-c-type-syntax}{mac}.
+can be extended in order to support new classes: see \descref{mac}{defctype},
+\descref{mac}{c-type-alias} and \descref{mac}{define-c-type-syntax}.
 
 The descriptions of each of the various classes include descriptions of the
 initargs which may be passed to @|make-instance| when constructing a new
@@ -81,14 +83,17 @@ 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 \descref{print-c-type}[function]{gf} prints a C type value using
+\item The \descref{gf}{print-c-type}[function] 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
+\item The \descref{gf}{pprint-c-type}[function] 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.
 
+\begin{describe}{fun}{c-name-case @<name> @> @<string>}
+\end{describe}
+
 
 \subsection{The C type root class} \label{sec:clang.c-types.root}
 
@@ -123,9 +128,9 @@ type specifier.  Type specifiers fit into two syntactic categories.
 \end{describe}
 
 \begin{describe}{mac}
-    {defctype \=@{ @<name> @! (@<name>^+) @} @<type-spec> \+ \\
-                @[[ @|:export| @<export-flag> @]]^* \-
-       \nlret @<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>.
@@ -149,10 +154,10 @@ type specifier.  Type specifiers fit into two syntactic categories.
 \end{describe}
 
 \begin{describe}{mac}
-    {define-c-type-syntax @<name> @<lambda-list> \\ \ind
-      @[[ @<declaration>^* @! @<doc-string> @]] \\
-      @<form>^* \-
-     \nlret @<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
@@ -164,8 +169,21 @@ type specifier.  Type specifiers fit into two syntactic categories.
   type specifiers among its arguments.
 \end{describe}
 
-\begin{describe}{fun}{expand-c-type-spec @<type-spec> @> @<form>}
+\begin{describe}{gf}{expand-c-type-spec @<type-spec> @> @<form>}
   Returns the Lisp form that @|(c-type @<type-spec>)| would expand into.
+
+  If @<type-spec> is a list, then \descref{gf}{expand-c-type-form} is
+  invoked.
+\end{describe}
+
+\begin{describe}{gf}{expand-c-type-form @<head> @<tail> @> @<form>}
+  Returns the Lisp form that @|(c-type (@<head> . @<tail>))| would expand
+  into.
+\end{describe}
+
+\begin{describe}{cty}{lisp @<form>^*}
+  Evaluates the @<form>s as an implicit @|progn|, and returns the value(s) of
+  the final @<form> as a C type.
 \end{describe}
 
 \begin{describe}{gf}
@@ -180,6 +198,28 @@ type specifier.  Type specifiers fit into two syntactic categories.
   default method.
 \end{describe}
 
+\begin{describe*}
+    {\dhead{sym}{c-type}
+     \dhead{meth}{symbol,(eql 'c-type)}
+                 {documentation (@<symbol> symbol)
+                                (@<doc-type> (eql 'c-type))}
+     \dhead{meth}{symbol,(eql 'c-type)}
+                 {setf \=(documentation (@<symbol> symbol)
+                                        (@<doc-type> (eql 'c-type))) \\
+                       \>@<string>}}
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{sym}{c-type-form}
+     \dhead{meth}{symbol,(eql 'c-type-form)}
+                 {documentation (@<symbol> symbol)
+                                (@<doc-type> (eql 'c-type-form))}
+     \dhead{meth}{symbol,(eql 'c-type-form)}
+                 {setf \=(documentation (@<symbol> symbol)
+                                        (@<doc-type> (eql 'c-type-form))) \\
+                       \>@<string>}}
+\end{describe*}
+
 
 \subsection{Comparing C types} \label{sec:clang.c-types.cmp}
 
@@ -198,12 +238,12 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
 
   The generic function @|c-type-equal-p| uses the @|and| method combination.
 
-  \begin{describe}{meth}{c-type-equal-p @<c-type>_1 @<c-type>_2}
+  \begin{describe}{meth}{t,t}{c-type-equal-p @<c-type>_1 @<c-type>_2}
     A default primary method for @|c-type-equal-p| is defined.  It simply
     returns @|nil|.  This way, methods can specialize on both arguments
     without fear that a call will fail because no methods are applicable.
   \end{describe}
-  \begin{describe}{ar-meth}{c-type-equal-p @<c-type>_1 @<c-type>_2}
+  \begin{describe}{ar-meth}{}{c-type-equal-p @<c-type>_1 @<c-type>_2}
     A default around-method for @|c-type-equal-p| is defined.  It returns
     true if @<c-type>_1 and @<c-type>_2 are @|eql|; otherwise it delegates to
     the primary methods.  Since several common kinds of C types are interned,
@@ -248,19 +288,19 @@ 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
-  \descref{maybe-in-parens}[macro]{mac}.
+  \descref{mac}{maybe-in-parens}[macro].
 
   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 \descref{c-type-space}[function]{fun}.
+  trailing space.  See also the \descref{fun}{c-type-space}[function].
 
   Every concrete subclass of @|c-type| is expected to provide a primary
   method on this function.  There is no default primary method.
 
-  \begin{describe}{ar-meth}{pprint-c-type @<c-type> @<stream> @<kernel>}
+  \begin{describe}{ar-meth}{}{pprint-c-type @<c-type> @<stream> @<kernel>}
     A default around method is defined on @|pprint-c-type| which `canonifies'
     non-function @<kernel> arguments.  In particular:
     \begin{itemize}
@@ -298,6 +338,29 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
 \subsection{Type qualifiers and qualifiable types}
 \label{sec:clang.ctypes.qual}
 
+Qualifiers -- @|const|, @|volatile|, and so on -- are represented as lists of
+keywords attached to types.  Not all C types can carry qualifiers: notably,
+function and array types cannot be qualified.
+
+For the most part, the C qualifier keywords correspond to like-named Lisp
+keywords, only the Lisp keyword names are in uppercase.  The correspondence
+is shown in \xref{tab:clang.ctypes.qual}.
+
+\begin{table}
+  \begin{tabular}[C]{*2{>{\codeface}l}l}                           \hlx*{hv}
+    \thd{C name}        & \thd{Lisp name}                       \\ \hlx{vhv}
+    _Atomic             & :atomic                               \\
+    const               & :const                                \\
+    restrict            & :restrict                             \\
+    volatile            & :volatile                             \\ \hlx*{vh}
+  \end{tabular}
+  \caption{C and Lisp qualifier names} \label{tab:clang.ctypes.qual}
+\end{table}
+
+The default behaviour, on output, is to convert keywords to lowercase and
+hope for the best: special cases can be dealt with by adding appropriate
+methods to \descref{gf}{c-qualifier-keyword}.
+
 \begin{describe}{cls}{qualifiable-c-type (c-type) \&key :qualifiers}
   The class @|qualifiable-c-type| describes C types which can bear
   `qualifiers' (\Cplusplus\ calls them `cv-qualifiers'): @|const|,
@@ -314,12 +377,16 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   The class @|qualifiable-c-type| is abstract.
 \end{describe}
 
+\begin{describe}{fun}
+    {canonify-qualifiers @<qualifiers> @> @<canonfied-qualifiers>}
+\end{describe}
+
 \begin{describe}{gf}{c-type-qualifiers @<c-type> @> @<list>}
   Returns the qualifiers of the @|qualifiable-c-type| instance @<c-type> as
   an immutable list.
 \end{describe}
 
-\begin{describe}{fun}{qualify-type @<c-type> @<qualifiers> @> @<c-type>}
+\begin{describe}{fun}{qualify-c-type @<c-type> @<qualifiers> @> @<c-type>}
   The argument @<c-type> must be an instance of @|qualifiable-c-type|,
   currently bearing no qualifiers, and @<qualifiers> a list of qualifier
   keywords.  The result is a C type object like @<c-type> except that it
@@ -335,6 +402,124 @@ argument lists for methods.  This is done by @|c-type-equal-p|.
   non-null then the final character of the returned string will be a space.
 \end{describe}
 
+\begin{describe}{gf}{c-qualifier-keyword @<qualifier> @> @<string>}
+  Return, as a string, the C keyword corresponding to the Lisp @<qualifier>.
+
+  There is a standard method, which deals with many qualifiers.  Additional
+  methods exist for qualifier keywords which need special handling, such as
+  @|:atomic|; they are not listed here explicitly.
+
+  \begin{describe}{meth}{keyword}
+      {c-qualifier-keyword @<keyword> @> @<string>}
+    Returns the @<keyword>'s print-name, in lower case.  This is sufficient
+    for the standard qualifiers @|:const|, @|:restrict|, and @|:volatile|.
+  \end{describe}
+\end{describe}
+
+\begin{describe}{fun}{c-type-qualifier-keywords @<c-type> @> @<list>}
+  Return the @<c-type>'s qualifiers, as a list of C keyword names.
+\end{describe}
+
+
+\subsection{Storage specifiers} \label{sec:clang.ctypes.specs}
+
+Some declaration specifiers, mostly to do with how to store the specific
+object in question, are determinedly `top level', and, unlike qualifiers,
+don't stay attached to the base type when acted on by declarator operators.
+Sod calls these `storage specifiers', though no such category exists in the C
+standard.  They have their own protocol, which is similar in many ways to
+that of C types.
+
+Every Lisp keyword is potentially a storage specifier, which simply maps to
+its lower-case print name in C; but other storage specifiers may be more
+complicated objects.
+
+\begin{describe*}
+    {\dhead{cls}{c-storage-specifiers-type (c-type)
+                                           \&key :subtype :specifiers}
+     \dhead{cty}{specs @<subtype> @<specifier>^*}}
+  A type which carries storage specifiers.  The @<subtype> is the actual
+  type, and may be any C type; the @<specifiers> are a list of
+  storage-specifier objects.
+
+  The type specifier @|specs| wraps the @<subtype> in a
+  @|c-storage-specifiers-type|, carrying the @<specifier>s, which are a list
+  of storage specifiers in S-expression notation.
+\end{describe*}
+
+\begin{describe}{fun}{c-type-specifiers @<type> @> @<list>}
+  Returns the list of type specifiers attached to the @<type> object, which
+  must be a @|c-storage-specifiers-type|.
+\end{describe}
+
+\begin{describe}{mac}
+    {define-c-storage-specifier-syntax @<name> @<lambda-list> \\ \ind
+      @[[ @<declaration>^* @! @<doc-string> @]] \\
+      @<form>^* \-
+     \nlret @<name>}
+
+  Defines the symbol @<name> as a new storage-specifier operator.  When a
+  list of the form @|(@<name> @<argument>^*)| is used as a storage specifier,
+  the @<argument>s are bound to fresh variables according to the
+  @<lambda-list> (a destructuring lambda-list) and the @<form>s evaluated in
+  order in the resulting lexical environment as an implicit @<progn>.  The
+  value should be a Lisp form which will evaluate to the storage-specifier
+  object described by the arguments.
+
+  The @<form>s may call @|expand-c-storage-specifier| in order to recursively
+  expand storage specifiers among its arguments.
+\end{describe}
+
+\begin{describe}{gf}{expand-c-storage-specifier @<spec> @> @<form>}
+  Returns the Lisp form that @<spec> expands to within @|(c-type (specs
+  @<subtype> @<spec>))|.
+
+  If @<spec> is a list, then \descref{gf}{expand-c-storage-specifier-form} is
+  invoked.
+\end{describe}
+
+\begin{describe}{gf}{expand-c-storage-specifier-form @<spec> @> @<form>}
+  Returns the Lisp form that @|(@<head> . @<tail>)| expands to within
+  @|(c-type (specs @<subtype> (@<head> . @<tail>)))|.
+\end{describe}
+
+\begin{describe}{cstg}{lisp @<form>^*}
+  Evaluates the @<form>s as an implicit @|progn|, and returns the value(s) of
+  the final @<form> as a storage-specifier.
+\end{describe}
+
+\begin{describe}{gf}{pprint-c-storage-specifier @<spec> @<stream>}
+  Prints the storage-specifier @<spec> to @<stream>, in C syntax.
+\end{describe}
+
+\begin{describe}{gf}
+    {print-c-storage-specifier @<stream> @<spec>
+                               \&optional @<colon> @<atsign>}
+\end{describe}
+
+\begin{describe}{fun}{wrap-c-type @<func> @<base-type> @> @<c-type>}
+  Apply @<func> to the underlying C type of @<base-type> to create a new
+  `wrapped' type, and attach the storage specifiers of @<base-type> to the
+  wrapped type.
+
+  If @<base-type> is \emph{not} a @|c-storage-specifiers-type|, then return
+  @|(funcall @<func> @<base-type>)|.  Otherwise, return a new
+  @|c-storage-specifiers-type|, with the same specifiers, but whose subtype
+  is the result of applying @<func> to the subtype of the original
+  @<base-type>.
+\end{describe}
+
+\begin{describe*}
+    {\dhead{cls}{alignas-storage-specifier () \&key :alignment}
+     \dhead{cstg}{alignas @<alignment>}}
+  The class of \mbox{@|_Alignas|} storage specifiers; an instance denotes the
+  specifier \mbox{@|_Alignas(@<alignment>)|}.  The @<alignment> parameter may
+  be any printable object, but is usually a string or C fragment.
+
+  The storage specifier form @|alignas| returns a storage specifier
+  \mbox{@|_Alignas(@<alignment>)|}, where @<alignment> is evaluated.
+\end{describe*}
+
 
 \subsection{Leaf types} \label{sec:clang.c-types.leaf}
 
@@ -360,6 +545,22 @@ In Sod, the leaf types are
   Two simple type objects are equal if and only if they have @|string=| names
   and matching qualifiers.
 
+  \def\x#1{\desclabel{cty}{#1}}
+  \def\y#1{\desclabel{const}{c-type-#1}\x{#1}}
+  \y{bool} \y{wchar-t}
+  \y{int} \x{signed} \y{unsigned} \y{signed-char}
+  \crossproduct\y{{{}{unsigned-}}{{char}{short}{long}{long-long}}}
+  \crossproduct\x{{{}{signed-}{unsigned-}}{{short}{long}{long-long}}{{-int}}}
+  \crossproduct\x{{{signed-}{unsigned-}}{{int}}}
+  \crossproduct\x{{{signed-}}{{short}{int}{long}{long-long}}}
+  \crossproduct\x{{{s}{u}}{{char}{short}{int}{long}{llong}}} \x{llong}
+  \y{size-t} \y{ptrdiff-t} \y{float}
+  \y{double} \y{long-double} \y{float-imaginary} \y{double-imaginary}
+  \y{long-double-imaginary} \y{float-complex} \y{double-complex}
+  \y{long-double-complex} \y{va-list} \y{void}
+  \crossproduct\y{{{int}{uint}}{{}{-least}{-fast}}{{8}{16}{32}{64}}{{-t}}}
+  \crossproduct\y{{{int}{uint}}{{ptr}{max}}{{-t}}}
+
   A number of symbolic type specifiers for builtin types are predefined as
   shown in \xref{tab:codegen.c-types.simple}.  These are all defined as if by
   @|define-simple-c-type|, so can be used to construct qualified types.
@@ -394,6 +595,18 @@ In Sod, the leaf types are
                           @|ullong|                             \\ \hlx{v}
     @|size_t|           & @|size-t|                             \\ \hlx{}
     @|ptrdiff_t|        & @|ptrdiff-t|                          \\ \hlx{v}
+    @|int$n$_t|         & @|int$n$-t|
+                          (for $n \in \{ @|8|, @|16|, @|32|, @|64| \}$)
+                                                                \\ \hlx{}
+    @|uint$n$_t|        & @|uint$n$-t|                          \\ \hlx{}
+    @|int_least$n$_t|   & @|int_least$n$-t|                     \\ \hlx{}
+    @|uint_least$n$_t|  & @|uint_least$n$-t|                    \\ \hlx{}
+    @|int_fast$n$_t|    & @|int_fast$n$-t|                      \\ \hlx{}
+    @|uint_fast$n$_t|   & @|uint_fast$n$-t|                     \\ \hlx{v}
+    @|intptr_t|         & @|intptr-t|                           \\ \hlx{}
+    @|uintptr_t|        & @|uintptr-t|                          \\ \hlx{}
+    @|intmax_t|         & @|intmax-t|                           \\ \hlx{}
+    @|uintmax_t|        & @|uintmax-t|                          \\ \hlx{v}
     @|float|            & @|float|                              \\ \hlx{}
     @|double|           & @|double|                             \\ \hlx{}
     @|long double|      & @|long-double|                        \\ \hlx{v}
@@ -424,23 +637,35 @@ In Sod, the leaf types are
 \end{describe}
 
 \begin{describe}{mac}
-    {define-simple-c-type \=@{ @<name> @! (@<name>^+) @} @<string> \+ \\
-                            @[[ @|:export| @<export-flag> @]] \-
-      \nlret @<name>}
+    {define-simple-c-type
+       \=@{ @<name> @! (@<name>^+) @}
+         @{ @<string> @! (@<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>
+  type whose name is the value of (the first) @<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).
+  name is (the first) @<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.
+  Each of the @<string>s is associated with the resulting type for retrieval
+  by \descref{fun}{find-simple-c-type}.  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}{fun}
+    {find-simple-c-type @<string> @> @{ @<simple-c-type> @! @|nil| @}}
+  If @<string> is the name of a simple C type, as established by the
+  \descref{mac}{define-simple-c-type}[macro], then return the corresponding
+  @|simple-c-type| object; otherwise, return @|nil|.
+\end{describe}
+
 \begin{describe}{cls}{tagged-c-type (qualifiable-c-type)
     \&key :qualifiers :tag}
   Provides common behaviour for C tagged types.  A @<tag> is a string
@@ -457,6 +682,14 @@ In Sod, the leaf types are
   structs and unions.
 \end{boxy}
 
+\begin{describe}{gf}{c-type-tag @<c-type> @> @<keyword>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-c-tagged-type @<kind> @<tag> \&optional @<qualifiers>
+      @> @<tagged-type>}
+\end{describe}
+
 \begin{describe}{gf}{c-tagged-type-kind @<c-type> @> @<keyword>}
   Returns a keyword classifying the tagged @<c-type>: one of @|:enum|,
   @|:struct| or @|:union|.  User-defined subclasses of @|tagged-c-type|
@@ -475,14 +708,16 @@ In Sod, the leaf types are
   type class as a symbol.
 \end{describe}
 
-\begin{describe}{cls}{c-enum-type (tagged-c-type) \&key :qualifiers :tag}
+\begin{describe*}
+    {\dhead{cls}{c-enum-type (tagged-c-type) \&key :qualifiers :tag}
+     \dhead{cty}{enum @<tag> @<qualifier>^*}}
   Represents a C enumerated type.  An instance denotes the C type @|enum|
   @<tag>.  See the direct superclass @|tagged-c-type| for details.
 
-  The type specifier @|(enum @<tag> @<qualifier>^*)| returns the (unique
-  interned) enumerated type with the given @<tag> and @<qualifier>s (all
-  evaluated).
-\end{describe}
+  The type specifier @|enum| returns the (unique interned) enumerated type
+  with the given @<tag> and @<qualifier>s (all evaluated).
+\end{describe*}
+
 \begin{describe}{fun}
     {make-enum-type @<tag> \&optional @<qualifiers> @> @<c-enum-type>}
   Return the (unique interned) C type object for the enumerated C type whose
@@ -490,14 +725,16 @@ In Sod, the leaf types are
   keywords).
 \end{describe}
 
-\begin{describe}{cls}{c-struct-type (tagged-c-type) \&key :qualifiers :tag}
+\begin{describe*}
+    {\dhead{cls}{c-struct-type (tagged-c-type) \&key :qualifiers :tag}
+     \dhead{cty}{struct @<tag> @<qualifier>^*}}
   Represents a C structured type.  An instance denotes the C type @|struct|
   @<tag>.  See the direct superclass @|tagged-c-type| for details.
 
-  The type specifier @|(struct @<tag> @<qualifier>^*)| returns the (unique
-  interned) structured type with the given @<tag> and @<qualifier>s (all
-  evaluated).
-\end{describe}
+  The type specifier @|struct| returns the (unique interned) structured type
+  with the given @<tag> and @<qualifier>s (all evaluated).
+\end{describe*}
+
 \begin{describe}{fun}
     {make-struct-type @<tag> \&optional @<qualifiers> @> @<c-struct-type>}
   Return the (unique interned) C type object for the structured C type whose
@@ -505,15 +742,17 @@ In Sod, the leaf types are
   keywords).
 \end{describe}
 
-\begin{describe}{cls}{c-union-type (tagged-c-type) \&key :qualifiers :tag}
+\begin{describe*}
+    {\dhead{cls}{c-union-type (tagged-c-type) \&key :qualifiers :tag}
+     \dhead{cty}{union @<tag> @<qualifier>^*}}
   Represents a C union type.  An instance denotes the C type @|union|
   @<tag>.  See the direct superclass @|tagged-c-type|
   for details.
 
-  The type specifier @|(union @<tag> @<qualifier>^*)| returns the (unique
-  interned) union type with the given @<tag> and @<qualifier>s (all
-  evaluated).
-\end{describe}
+  The type specifier @|union| returns the (unique interned) union type with
+  the given @<tag> and @<qualifier>s (all evaluated).
+\end{describe*}
+
 \begin{describe}{fun}
     {make-union-type @<tag> \&optional @<qualifiers> @> @<c-union-type>}
   Return the (unique interned) C type object for the union C type whose tag
@@ -534,29 +773,67 @@ protocol.
 \end{describe}
 
 
+\subsection{Atomic types} \label{sec:clang.c-types.atomic}
+
+Atomic types are compound types.  The subtype of an atomic type is simply the
+underlying type of the object.  Note that, as far as Sod is concerned, atomic
+types are not the same as atomic-qualified types: you must be consistent
+about which you use.
+
+\begin{describe*}
+    {\dhead{cls}{c-atomic-type (qualifiable-c-type)
+                               \&key :qualifiers :subtype}
+     \dhead{cty}{atomic @<type-spec> @<qualifier>^*}}
+  Represents an atomic type.  An instance denotes the C type
+  @|_Atomic(@<subtype>)|.
+
+  The @<subtype> may be any C type.\footnote{%
+    C does not permit atomic function or array types.} %
+  Two atomic types are equal if and only if their subtypes are equal and they
+  have matching qualifiers.  It is possible, though probably not useful, to
+  have an atomic-qualified atomic type.
+
+  The type specifier @|atomic| returns a type qualified atomic @<subtype>,
+  where @<subtype> is the type specified by @<type-spec> and the
+  @<qualifier>s are qualifier keywords (which are evaluated).
+\end{describe*}
+
+\begin{describe}{fun}
+    {make-atomic-type @<c-type> \&optional @<qualifiers> @> @<c-atomic-type>}
+  Return an object describing the type qualified atomic @<subtype>.  If
+  @<subtype> is interned, then the returned atomic type object is interned
+  also.
+\end{describe}
+
+
 \subsection{Pointer types} \label{sec:clang.c-types.pointer}
 
 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}
+\begin{describe*}
+    {\dhead{cls}{c-pointer-type (qualifiable-c-type)
+                                \&key :qualifiers :subtype}
+     \dhead{cty}{* @<type-spec> @<qualifier>^*}
+     \dhead{cty}{string}
+     \dhead{cty}{const-string}}
   Represents a C pointer type.  An instance denotes the C type @<subtype>
   @|*|@<qualifiers>.
 
   The @<subtype> may be any C type.  Two pointer types are equal if and only
   if their subtypes are equal and they have matching qualifiers.
 
-  The type specifier @|(* @<type-spec> @<qualifier>^*)| returns a type
-  qualified pointer-to-@<subtype>, where @<subtype> is the type specified by
-  @<type-spec> and the @<qualifier>s are qualifier keywords (which are
-  evaluated).  The synonyms @|ptr| and @|pointer| may be used in place of the
-  star @`*'.
+  \desclabel{cty}{ptr}
+  \desclabel{cty}{pointer}
+  The type specifier @|*| returns a type qualified pointer-to-@<subtype>,
+  where @<subtype> is the type specified by @<type-spec> and the
+  @<qualifier>s are qualifier keywords (which are evaluated).  The synonyms
+  @|ptr| and @|pointer| may be used in place of the star @`*'.
 
   The symbol @|string| is a type specifier for the type pointer to
   characters; the symbol @|const-string| is a type specifier for the type
   pointer to constant characters.
-\end{describe}
+\end{describe*}
 
 \begin{describe}{fun}
     {make-pointer-type @<c-type> \&optional @<qualifiers>
@@ -572,7 +849,11 @@ points to.
 Arrays implement the compound-type protocol.  The subtype of an array type is
 the array element type.
 
-\begin{describe}{cls}{c-array-type (c-type) \&key :subtype :dimensions}
+\begin{describe*}
+    {\dhead{cls}{c-array-type (c-type) \&key :subtype :dimensions}
+     \dhead{cty}{[] @<type-spec> @<dimension>^*}}
+  \desclabel{cty}{array}[|(]
+  \desclabel{cty}{vec}[|(]
   Represents a multidimensional C array type.  The @<dimensions> are a list
   of dimension specifiers $d_0$, $d_1$, \ldots, $d_{n-1}$; an instance then
   denotes the C type @<subtype> @|[$d_0$][$d_1$]$\ldots$[$d_{n-1}$]|.  An
@@ -589,12 +870,15 @@ the array element type.
   $d_1$ of \ldots\ arrays of $d_{n-1}$ elements of type @<subtype>.  We shall
   continue to abuse terminology and refer to multidimensional arrays.
 
-  The type specifier @|([] @<type-spec> @<dimension>^*)| constructs a
-  multidimensional array with the given @<dimension>s whose elements have the
-  type specified by @<type-spec>.  If no dimensions are given then a
-  single-dimensional array with unspecified extent.  The synonyms @|array|
-  and @|vector| may be used in place of the brackets @`[]'.
-\end{describe}
+  The type specifier @|[]| constructs a multidimensional array with the given
+  @<dimension>s whose elements have the type specified by @<type-spec>.  If
+  no dimensions are given then a single-dimensional array with unspecified
+  extent.  The synonyms @|array| and @|vec| may be used in place of the
+  brackets @`[]'.
+
+  \desclabel{cty}{array}[|)]
+  \desclabel{cty}{vec}[|)]
+\end{describe*}
 
 \begin{describe}{fun}
     {make-array-type @<subtype> @<dimensions> @> @<c-array-type>}
@@ -623,7 +907,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>.
 
@@ -632,14 +917,21 @@ 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.
+
+  A @<default> may be supplied.  If the argument is used in a
+  keyword-argument list (e.g., in a \descref{cls}{c-keyword-function-type}
+  [object]), 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*}
     {\dhead{fun}{argument-name @<argument> @> @<name>}
-     \dhead{fun}{argument-type @<argument> @> @<c-type>}}
-  Accessor functions for @|argument| objects.  They return the name (for
-  @|argument-name|) or type (for @|argument-type|) from the object, as passed
-  to @|make-argument|.
+     \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}
@@ -652,11 +944,13 @@ function type is the type of the function's return value.
   including file from defining such names as macros.  This generic function
   is used to convert names into a safe form.
 
-  \begin{describe}{meth}{commentify-argument-name (@<name> null) @> nil}
+  \begin{describe}{meth}{null}
+      {commentify-argument-name (@<name> null) @> nil}
     Returns nil: if the argument name is already omitted, it's safe for use
     in a header file.
   \end{describe}
-  \begin{describe}{meth}{commentify-argument-name (@<name> t) @> @<string>}
+  \begin{describe}{meth}{t}
+      {commentify-argument-name (@<name> t) @> @<string>}
     Returns the print form of @<name> wrapped in a C comment, as
     @`/*@<name>*/'.
   \end{describe}
@@ -676,7 +970,16 @@ function type is the type of the function's return value.
   unchanged.
 \end{describe}
 
-\begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments}
+\begin{describe*}
+    {\dhead{cls}{c-function-type (c-type) \&key :subtype :arguments}
+     \dhead*{cty}{fun @<return-type>
+                      @{ (@<arg-name> @<arg-type>) @}^*
+                      @[:ellipsis @! . @<form>@]}}
+  \desclabel{cty}{()}[|(]
+  \desclabel{cty}{fn}[|(]
+  \desclabel{cty}{func}[|(]
+  \desclabel{cty}{function}[|(]
+  \descindex{cty}{fun}[|(]
   Represents C function types.  An instance denotes the type of a C
   function which accepts the @<arguments> and returns @<subtype>.
 
@@ -694,19 +997,13 @@ 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
-  \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
+  The type specifier @|fun| 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;
@@ -715,7 +1012,7 @@ function type is the type of the function's return value.
     arguments; or
   \item a possibly-improper list tail, beginning with an atom either as a
     list item or as the final list cdr, indicating that the entire list tail
-    is Lisp expression which is to be evaluated to compute the remaining
+    is Lisp expression which is to be evaluated to compute the remaining
     arguments.
   \end{itemize}
   A tail expression may return a list of @|argument| objects, optionally
@@ -723,28 +1020,99 @@ function type is the type of the function's return value.
 
   For example,
   \begin{prog}
-    (c-type (fun \=(lisp (c-type-subtype other-func)) \+ \\
+    (c-type (fun \=(lisp (c-type-subtype other-func))         \+\\
                    ("first" int) . (c-function-arguments other-func))
   \end{prog}
   evaluates to a function type like @|other-func|, only with an additional
   argument of type @|int| added to the front of its argument list.  This
   could also have been written
   \begin{prog}
-    (let (\=(args (c-function-arguments other-func)) \+ \\
-            (ret (c-type-subtype other-func))) \- \\ \ind
+    (let (\=(args (c-function-arguments other-func))          \+\\
+            (ret (c-type-subtype other-func)))                \-\\ \ind
       (c-type (fun \=(lisp ret) ("first" int) . args)
   \end{prog}
-\end{describe}
+  \descindex{cty}{fun}[|)]
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{cls}{c-keyword-function-type (c-function-type)
+                                         \&key :subtype :arguments :keywords}
+     \dhead{cty}{fun \=@<return-type>
+                       @{ (@<arg-name> @<arg-type>) @}^*      \+\\
+                       @{ \=:keys @{ (@<kw-name> @<kw-type>
+                                      @[@<kw-default>@]) @}^*
+                               @[. @<form>@] @!               \+\\
+                             . @<form> @}}}
+  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 (or any of its synonyms) used for ordinary C function types.
+  Either the symbol @|:keys| must appear literally in the specifier, or the
+  @<form> must evaluate 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{cls}{c-function-type} 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.
+
+  \descindex{cty}{()}[|)]
+  \descindex{cty}{fn}[|)]
+  \descindex{cty}{func}[|)]
+  \descindex{cty}{function}[|)]
+\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{cls}{c-keyword-function-type}[object] 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}
     {c-function-arguments @<c-function-type> @> @<arguments>}
-  Return the arguments list of the @<c-function-type>.
+  Return the (non-keyword) argument list of the @<c-function-type>.
+\end{describe}
+
+\begin{describe}{gf}
+    {c-function-keywords @<c-function-type> @> @<keywords>}
+  Return the keyword-argument list of the @<c-function-type>.
 \end{describe}
 
 \begin{describe}{fun}
@@ -756,6 +1124,54 @@ 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{var}{*sod-ap*}[variable].  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 @<what-function> @<lists> @> @<list>}
+  Merge a number of keyword-argument lists together and return the result.
+
+  The @<what-function> is either nil or a function designator; see below.
+
+  The @<lists> parameter is a list consisting of a number of
+  @|(@<report-function> . @<args>)| pairs: in each pair, @<report-function>
+  is either nil or a function designator, and @<args> is a list of
+  \descref{cls}{argument} objects.
+
+  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, a continuable
+  error will be signalled, and one of the conflicting argument types will be
+  chosen arbitrarily.  The @<what-function> will be called to establish
+  information which will be reported to the user.  It will be called with no
+  arguments and is expected to return two values:
+  \begin{itemize}
+  \item a file location @<floc> or other object acceptable to
+    \descref{gf}{file-location}, to be used as the location of the main
+    error; and
+  \item an object @<what>, whose printed representation should be a noun
+    phrase describing the object for which the argument lists are being
+    combined.
+  \end{itemize}
+  The phrasing of the error message is `type mismatch in @<what>'.  Either,
+  or both, of @<floc> and @<what> may be nil, though this is considered poor
+  practice; if @<what-function> is nil, this is equivalent to a function
+  which returns two nil values.  Following the error, the @<report-function>s
+  for the @<args> lists containing the conflicting argument objects are
+  called, in an arbitrary order, with a single argument which is the
+  offending @|argument| object; the function is expected to issue information
+  messages (see \descref{fun}{info}) to give more detail for diagnosing the
+  conflict.  If a @<report-function> is nil, then nothing happens; this is
+  considered poor practice.
+\end{describe}
+
 \begin{describe}{fun}
     {pprint-c-function-type @<return-type> @<stream>
                             @<print-args> @<print-kernel>}
@@ -767,7 +1183,7 @@ function type is the type of the function's return value.
   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}.
+  following the \descref{gf}{pprint-c-type}[protocol].
 
   The @<print-args> function is given a single argument, which is the
   @<stream> to print on.  It should not print the surrounding parentheses.
@@ -781,7 +1197,7 @@ function type is the type of the function's return value.
 \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
+  The @<args> is a list of \descref{cls}{argument}[objects], optionally
   containing an @|:ellipsis| marker.  The function returns true if any
   arguments were actually printed.
 \end{describe}
@@ -802,9 +1218,11 @@ function type is the type of the function's return value.
 
 \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{cls}{c-class-type (simple-c-type)
+                              \&key :class :tag :qualifiers :name}
+     \dhead{cty}{class @<name> @<qualifier>^*}}
+\end{describe*}
 
 \begin{describe*}
     {\dhead{gf}{c-type-class @<class-type> @> @<class>}
@@ -818,10 +1236,6 @@ function type is the type of the function's return value.
     {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}
 
@@ -856,8 +1270,7 @@ Temporary names are represented by objects which implement a simple protocol.
 
 \begin{describe*}
     {\dhead{gf}{var-in-use-p @<var> @> @<generalized-boolean>}
-     \dhead[setf var-in-use-p]
-       {gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
+     \dhead{gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
 \end{describe*}
 
 \subsubsection{Temporary name objects}
@@ -867,17 +1280,20 @@ Temporary names are represented by objects which implement a simple protocol.
   subclasses, but is also usable on its own.
 \end{describe}
 
-\begin{describe}{meth}
+\begin{describe}{gf}{temp-tag @<name> @> @<tag>}
+\end{describe}
+
+\begin{describe}{meth}{temporary-name}
     {commentify-argument-name (@<name> temporary-name) @> nil}
 \end{describe}
 
 \begin{table}
   \begin{tabular}[C]{*2{>{\codeface}l}}                            \hlx*{hv}
-    \thd{\textbf{Class}} & \thd{\textbf{Name format}}           \\ \hlx{vhv}
-    temporary-name              & @<tag>                        \\
-    temporary-argument          & sod__a@<tag>                  \\
-    temporary-function          & sod__f@<tag>                  \\
-    temporary-variable          & sod__v@<tag>                  \\ \hlx*{vh}
+    \thd{Class}         & \thd{Name format}                     \\ \hlx{vhv}
+    temporary-name      & @<tag>                                \\
+    temporary-argument  & sod__a@<tag>                          \\
+    temporary-function  & sod__f@<tag>                          \\
+    temporary-variable  & sod__v@<tag>                          \\ \hlx*{vh}
   \end{tabular}
   \caption{Temporary name formats}
   \label{tab:codegen.codegen.temps-format}
@@ -899,11 +1315,13 @@ Temporary names are represented by objects which implement a simple protocol.
 \subsubsection{Well-known `temporary' names}
 
 \begin{table}
+  \def\x#1{\desclabel{var}{#1}}
+  \x{*sod-ap*} \x{*sod-master-ap*} \x{*null-pointer*}
   \begin{tabular}[C]{*2{>{\codeface}l}}                            \hlx*{hv}
-    \thd{\textbf{Variable}} & \thd{\textbf{Name format}}        \\ \hlx{vhv}
-    {}*sod-ap*                  & sod__ap                       \\
-    {}*sod-master-ap*           & sod__master_ap                \\
-    {}*null-pointer*            & NULL                          \\ \hlx*{vh}
+    \thd{Variable}      & \thd{Name format}                     \\ \hlx{vhv}
+    {}*sod-ap*          & sod__ap                               \\
+    {}*sod-master-ap*   & sod__master_ap                        \\
+    {}*null-pointer*    & NULL                                  \\ \hlx*{vh}
   \end{tabular}
   \caption{Well-known temporary names}
   \label{tab:codegen.codegen.well-known-temps}
@@ -919,16 +1337,16 @@ Temporary names are represented by objects which implement a simple protocol.
 \end{describe}
 
 \begin{describe}{mac}
-    {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*) \\ \ind
-      @[[ @<declaration>^* @! @<doc-string> @]] \\
-      @<form>^* \-
-     \nlret @<code>}
+    {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>) \\ \ind
-      @<declaration>^* \\
+        (@<stream> @<child> \&optional @<morep>)                \\ \ind
+      @<declaration>^*                                          \\
       @<form>^*}
 \end{describe}
 
@@ -939,8 +1357,8 @@ Temporary names are represented by objects which implement a simple protocol.
 \begin{table}
   \begin{tabular}[C]{ll>{\codeface}l}                              \hlx*{hv}
     \thd{Class name} &
-    \thd{Arguments} &
-    \thd{Output format}                                         \\ \hlx{vhv}
+                  \thd{Arguments} &
+                                             \thd{Output format}\\ \hlx{vhv}
     @|var|      & @<name> @<type> @|\&optional| @<init>
                                            & @<type> @<name> @[= @<init>@];
                                                                 \\ \hlx{v}
@@ -984,6 +1402,33 @@ Temporary names are represented by objects which implement a simple protocol.
   \label{tab:codegen.codegen.insts}
 \end{table}
 
+\begin{describe*}
+    {\dhead*{cls}{@<code>-inst (inst) \&key \dots}
+     \dhead*{fun}{make-@<code>-inst \dots}
+     \dhead*{gf}{inst-@<slot> @<inst> @> @<value>}}
+  \def\instclass#1#2#3{%
+    #1{cls}{#3-inst}[#2]%
+    #1{fun}{make-#3-inst}[#2]%
+  }
+  \def\instslot#1#2#3{#1{gf}{inst-#3}[#2]}
+  \def\makelabels#1#2{%
+    \def\x{\instclass{#1}{#2}}
+      \x{var} \x{set} \x{update} \x{cond} \x{return} \x{break} \x{continue}
+      \x{expr} \x{call} \x{banner} \x{block} \x{if} \x{for} \x{while}
+      \x{do-while} \x{function}
+    \def\x{\instslot{#1}{#2}}
+      \x{name} \x{type} \x{init} \x{var} \x{expr} \x{op} \x{cond} \x{conseq}
+      \x{alt} \x{func} \x{args} \x{control} \x{decls} \x{body} \x{update}
+      \x{banner} \x{banner-args}
+  }
+  \makelabels{\desclabel}{|(}
+
+  Sod provides a number of built-in instruction types generated by
+  \descref{mac}{definst}: see \xref{tab:codegen.codegen.insts}.
+
+  \makelabels{\descindex}{|)}
+\end{describe*}
+
 
 \subsection{Code generation} \label{sec:clang.codegen.codegen}
 
@@ -1034,10 +1479,10 @@ Temporary names are represented by objects which implement a simple protocol.
 \end{describe}
 
 \begin{describe}{mac}
-    {with-temporary-var (@<codegen> @<var> @<type>) \\ \ind
-      @<declaration>^* \\
-      @<form>^* \-
-     \nlret @<value>^*}
+    {with-temporary-var (@<codegen> @<var> @<type>)             \\ \ind
+      @<declaration>^*                                          \\
+      @<form>^*
+     \-\nlret @<value>^*}
 \end{describe}
 
 \begin{describe}{fun}{deliver-expr @<codegen> @<target> @<expr>}
@@ -1059,8 +1504,11 @@ Temporary names are represented by objects which implement a simple protocol.
 \begin{describe}{cls}{c-fragment () \&key :location :text}
 \end{describe}
 
-\begin{describe}{gf}{c-fragment-text @<fragment> @> @<string>}
-\end{describe}
+\begin{describe*}
+    {\dhead{gf}{c-fragment-text @<fragment> @> @<string>}
+     \dhead{meth}{c-fragment}
+       {file-location (@<fragment> c-fragment) @> @<floc>}}
+\end{describe*}
 
 \begin{describe}{fun}
     {scan-c-fragment @<scanner> @<end-chars>