X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/1f7d590d9c7b87442c8d8b6424ed4f769d377692..d5fdd49e70b734b791eb907706f92da5775e2a8b:/doc/clang.tex?ds=inline

diff --git a/doc/clang.tex b/doc/clang.tex
index c26ece5..aebc94d 100644
--- a/doc/clang.tex
+++ b/doc/clang.tex
@@ -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
@@ -34,24 +34,26 @@ The Sod translator represents C types in a fairly simple and direct way.
 However, because it spends a fair amount of its time dealing with C types, it
 provides a number of useful operations and macros.
 
-The class hierarchy is shown in~\xref{fig:proto.c-types}.
+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:proto.c-types}
+\label{fig:codegen.c-types.classes}
 \end{figure}
 
 C type objects are immutable unless otherwise specified.
@@ -65,11 +67,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{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{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
@@ -80,14 +83,18 @@ 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{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{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}
 
 \begin{describe}{cls}{c-type ()}
@@ -100,6 +107,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 +128,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 +138,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 +154,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
@@ -150,8 +169,16 @@ 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}{gf}
@@ -166,6 +193,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
@@ -183,12 +211,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,
@@ -196,6 +224,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,20 +261,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
-  @|maybe-in-parens| macro (page~\pageref{mac:maybe-in-parens}).
+  \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 @|c-type-space| function
-  (page~\pageref{fun:c-type-space}).
+  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}
@@ -265,7 +293,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,9 +307,33 @@ 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}
 
+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|,
@@ -290,18 +344,22 @@ 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}
 
+\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
@@ -311,12 +369,121 @@ 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}
 
+\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}{cls}
+    {c-storage-specifiers-type (c-type) \&key :subtype :specifiers}
+  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 @<subtype> @<specifier>^*)| 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}{gf}{pprint-c-storage-specifier @<spec> @<stream>}
+\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}{cls}{alignas-storage-specifier () \&key :alignment}
+  The class of @|_Alignas| storage specifiers; an instance denotes the
+  specifier @|_Alignas(@<alignment>)|.  The @<alignment> parameter may be any
+  printable object, but is usually a string or C fragment.
+
+  The storage specifier form @|(alignas @<alignment>)| returns a storage
+  specifier @|_Alignas(@<alignment>)|, where @<alignment> is evaluated.
+\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.
@@ -341,44 +508,77 @@ 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{const}{c-type-#1}}
+  \x{bool} \x{char} \x{wchar-t} \x{signed-char} \x{unsigned-char} \x{short}
+  \x{unsigned-short} \x{int} \x{unsigned} \x{long} \x{unsigned-long}
+  \x{long-long} \x{unsigned-long-long} \x{size-t} \x{ptrdiff-t} \x{float}
+  \x{double} \x{long-double} \x{float-imaginary} \x{double-imaginary}
+  \x{long-double-imaginary} \x{float-complex} \x{double-complex}
+  \x{long-double-complex} \x{va-list} \x{void}
+  \crossproduct\x{{{int}{uint}}{{}{-least}{-fast}}{{8}{16}{32}{64}}{{-t}}}
+  \crossproduct\x{{{int}{uint}}{{ptr}{max}}{{-t}}}
+
   A number of symbolic type specifiers for builtin types are predefined as
-  shown in \xref{tab:proto.c-types.simple}.  These are all defined as if by
+  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.
 \end{describe}
 
 \begin{table}
-  \begin{tabular}[C]{|l|l|}                                        \hlx{hv}
-    \textbf{C type}     & \textbf{Specifiers}                   \\ \hlx{vhv}
-    @|void|             & @|void|                               \\ \hlx{vhv}
-    @|char|             & @|char|                               \\ \hlx{v}
+  \begin{tabular}[C]{ll}                                           \hlx*{hv}
+    \thd{C type}        & \thd{Specifiers}                      \\ \hlx{vhv}
+    @|void|             & @|void|                               \\ \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}
-    @|signed char|      & @|signed-char|, @|schar|              \\ \hlx{vhv}
     @|short|            & @|short|, @|signed-short|, @|short-int|,
-                          @|signed-short-int| @|sshort|         \\ \hlx{v}
+                          @|signed-short-int| @|sshort|         \\ \hlx{}
     @|unsigned short|   & @|unsigned-short|, @|unsigned-short-int|,
-                          @|ushort|                             \\ \hlx{vhv}
+                          @|ushort|                             \\ \hlx{v}
     @|int|              & @|int|, @|signed|, @|signed-int|,
-                          @|sint|                               \\ \hlx{v}
-    @|unsigned int|     & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{vhv}
+                          @|sint|                               \\ \hlx{}
+    @|unsigned int|     & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{v}
     @|long|             & @|long|, @|signed-long|, @|long-int|,
-                          @|signed-long-int|, @|slong|          \\ \hlx{v}
+                          @|signed-long-int|, @|slong|          \\ \hlx{}
     @|unsigned long|    & @|unsigned-long|, @|unsigned-long-int|,
-                          @|ulong|                              \\ \hlx{vhv}
+                          @|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{vhv}
-    @|float|            & @|float|                              \\ \hlx{v}
-    @|double|           & @|double|                             \\ \hlx{vhv}
-    @|va_list|          & @|va-list|                            \\ \hlx{v}
-    @|size_t|           & @|size-t|                             \\ \hlx{v}
-    @|ptrdiff_t|        & @|ptrdiff-t|                          \\ \hlx{vh}
+                          @|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}
+    @|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:proto.c-types.simple}
+  \label{tab:codegen.c-types.simple}
 \end{table}
 
 \begin{describe}{fun}
@@ -394,13 +594,33 @@ 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> @! (@<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).
+
+  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)
@@ -419,6 +639,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|
@@ -445,6 +673,7 @@ In Sod, the leaf types are
   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
@@ -460,6 +689,7 @@ In Sod, the leaf types are
   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
@@ -483,6 +713,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 +725,43 @@ protocol.
   this means depends on the class of @<c-type>.
 \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}{cls}
+    {c-atomic-type (qualifiable-c-type) \&key :qualifiers :subtype}
+  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 @<type-spec> @<qualifier>^*)| 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 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}
@@ -513,7 +777,7 @@ to.
   evaluated).  The synonyms @|ptr| and @|pointer| may be used in place of the
   star @`*'.
 
-  The symbol @|string| is a type specifier for the type of pointer to
+  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}
@@ -521,15 +785,16 @@ to.
 \begin{describe}{fun}
     {make-pointer-type @<c-type> \&optional @<qualifiers>
       @> @<c-pointer-type>}
-  Return an object describing the type of qualified pointers to @<subtype>.
+  Return an object describing the type qualified pointer to @<subtype>.
   If @<subtype> is interned, then the returned pointer type object is
   interned also.
 \end{describe}
 
+
 \subsection{Array types} \label{sec:clang.c-types.array}
 
-Arrays implement the compound-type protocol.  The subtype of an array is the
-array element type.
+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}
   Represents a multidimensional C array type.  The @<dimensions> are a list
@@ -567,53 +832,625 @@ 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
+function type is the type of the function's return value.
+
 \begin{describe}{cls}{argument}
+  Represents an ordinary function argument.
 \end{describe}
 
 \begin{describe}{fun}{argumentp @<value> @> @<generalized-boolean>}
+  Decide whether @<value> is an @<argument> object: if so, return non-nil; if
+  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>.
+
+  The @<name> may be nil to indicate that the argument has no name: in this
+  case the argument will be formatted as an abstract declarator, which is not
+  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}{fun}{argument-name @<argument> @> @<string>}
-\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}{fun}{argument-type @<argument> @> @<c-type>}
+\begin{describe}{gf}
+    {commentify-argument-name @<name> @> @<commentified-name>}
+  Convert the argument name @<name> so that it's suitable to declare the
+  function in a header file.
+
+  Robust header files shouldn't include literal argument names in
+  declarations of functions or function types, since this restricts the
+  including file from defining such names as macros.  This generic function
+  is used to convert names into a safe form.
+
+  \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}{t}
+      {commentify-argument-name (@<name> t) @> @<string>}
+    Returns the print form of @<name> wrapped in a C comment, as
+    @`/*@<name>*/'.
+  \end{describe}
 \end{describe}
 
 \begin{describe}{fun}
-    {commentify-argument-name @<name> @> @<commentified-name>}
+    {commentify-argument-names @<arguments> @> @<commentified-arguments>}
+  Convert the @<arguments> list so that it's suitable for use in a header
+  file.
+
+  The @<arguments> list should be a list whose items are @|argument| objects
+  or the keyword @|:ellipsis|.  The return value is a list constructed as
+  follows.  For each @|argument| object in the input list, there is a
+  corresponding @|argument| object in the returned list, with the same type,
+  and whose name is the result of @|commentify-argument-name| applied to the
+  input argument name; an @|:ellipsis| in the input list is passed through
+  unchanged.
 \end{describe}
 
 \begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments}
-  Represents C function types.  An instance denotes the C type of a C
-  function which FIXME
+  Represents C function types.  An instance denotes the type of a C
+  function which accepts the @<arguments> and returns @<subtype>.
+
+  The @<arguments> are a possibly empty list.  All but the last element of
+  the list must be @|argument| objects; the final element may instead be the
+  keyword @|:ellipsis|, which denotes a variable argument list.
+
+  An @<arguments> list consisting of a single argument with type @|void| is
+  converted into an empty list.  On output as C code, an empty argument list
+  is written as @|void|.  It is not possible to represent a pre-ANSI C
+  function without prototypes.
+
+  Two function types are considered to be the same if their return types are
+  the same, and their argument lists consist of arguments with the same type,
+  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
+  \begin{itemize}
+  \item nothing, in which case the function's argument list consists only of
+    the explicit arguments;
+  \item the keyword @|:ellipsis|, as the final item in the type-specifier
+    list, indicating a variable argument list may follow the explicit
+    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 a 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
+  followed by an @|:ellipsis|.
+
+  For example,
+  \begin{prog}
+    (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
+      (c-type (fun \=(lisp ret) ("first" int) . args)
+  \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{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.
+\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 (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}
-    {make-c-type @<c-type> @<arguments> @> @<c-function-type>}
+    {commentify-function-type @<c-function-type> @> @<commentified-c-type>}
+  Return a commentified version of the @<c-function-type>.
+
+  The returned type has the same subtype as the given type, and the argument
+  list of the returned type is the result of applying
+  @|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}
-    {commentify-argument-names @<arguments> @> @<commentified-arguments>}
+    {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}
-    {commentify-function-type @<c-type> @> @<commentified-c-type>}
+    {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{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.
+
+  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{cls}{argument}[objects], 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}{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
+header file, are assigned names which are simple strings, perhaps fixed ones,
+perhaps constructed.  Other objects don't need meaningful names, and
+suitably unique constructed names would be tedious and most likely rather
+opaque.  Therefore Sod has an ability to construct \emph{temporary names}.
+
+These aren't temporary in the sense that they name C objects which have
+limited lifetimes at runtime.  Rather, the idea is that the names be
+significant only to small pieces of Lisp code, which will soon forget about
+them.
+
+\subsubsection{The temporary name protocol}
+Temporary names are represented by objects which implement a simple protocol.
+
+\begin{describe}{gf}{format-temporary-name @<var> @<stream>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{gf}{var-in-use-p @<var> @> @<generalized-boolean>}
+     \dhead{gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
+\end{describe*}
+
+\subsubsection{Temporary name objects}
+
+\begin{describe}{cls}{temporary-name () \&key :tag}
+  A temporary name object.  This is the root of a small collection of
+  subclasses, but is also usable on its own.
+\end{describe}
+
+\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{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}
+\end{table}
+
+\begin{describe}{cls}{temporary-argument (temporary-name) \&key :tag}
+\end{describe}
+
+\begin{describe}{cls}{temporary-function (temporary-name) \&key :tag}
+\end{describe}
+
+\begin{describe}{fun}{temporary-function @> @<name>}
+\end{describe}
+
+\begin{describe}{cls}
+    {temporary-variable (temporary-name) \&key :tag :in-use-p}
+\end{describe}
+
+\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{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}
+\end{table}
+
+
+\subsection{Instructions} \label{sec:clang.codegen.insts}
+
+\begin{describe}{cls}{inst () \&key}
+\end{describe}
+
+\begin{describe}{gf}{inst-metric @<inst>}
+\end{describe}
+
+\begin{describe}{mac}
+    {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>^*                                          \\
+      @<form>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {format-banner-comment @<stream> @<control> \&rest @<args>}
+\end{describe}
+
+\begin{table}
+  \begin{tabular}[C]{ll>{\codeface}l}                              \hlx*{hv}
+    \thd{Class name} &
+                  \thd{Arguments} &
+                                             \thd{Output format}\\ \hlx{vhv}
+    @|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> @|\&rest| @<args>
+                                           & @<func>(@<arg>_1,
+                                                     $\ldots$,
+                                                     @<arg>_n)  \\ \hlx{v}
+    @|banner|   & @<control> @|\&rest| @<args>
+                                           & /* @<banner> */    \\ \hlx{vhv}
+    @|block|    & @<decls> @<body>         & \{ @[@<decls>@] @<body> \}
+                                                                \\ \hlx{v}
+    @|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| &
+      \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}
+
+\begin{describe*}
+    {\dhead*{cls}{@<code>-inst (inst) \&key \dots}
+     \dhead*{fn}{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}
+
+\begin{describe}{gf}{codegen-functions @<codegen> @> @<list>}
+\end{describe}
+
+\begin{describe}{gf}
+    {ensure-var @<codegen> @<name> @<type> \&optional @<init>}
+\end{describe}
+
+\begin{describe}{gf}{emit-inst @<codegen> @<inst>}
+\end{describe}
+
+\begin{describe}{gf}{emit-insts @<codegen> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{emit-decl @<codegen> @<decl>}
+\end{describe}
+
+\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>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop @<codegen> @> @<decls> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop-block @<codegen> @> @<block-inst>}
+\end{describe}
+
+\begin{describe}{gf}
+    {codegen-pop-function @<codegen> @<name> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-add-function @<codegen> @<function>}
+\end{describe}
+
+\begin{describe}{fun}
+    {codegen-build-function @<codegen> @<name> @<type> @<vars> @<insts>
+      @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{temporary-var @<codegen> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{mac}
+    {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}
+
+\begin{describe}{cls}{codegen () \&key :vars :insts (:temp-index 0)}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Literal C code fragments} \label{sec:clang.fragment}
+
+\begin{describe}{cls}{c-fragment () \&key :location :text}
+\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>
+      @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{fun}
+    {parse-delimited-fragment @<scanner> @<begin> @<end> \&key :keep-end
+      \nlret @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
 %%%----- That's all, folks --------------------------------------------------
 
 %%% Local variables:
