%%% -*-latex-*-
%%%
%%% C language utilities
%%%
%%% (c) 2015 Straylight/Edgeware
%%%

%%%----- Licensing notice ---------------------------------------------------
%%%
%%% This file is part of the Sensble 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
%%% the Free Software Foundation; either version 2 of the License, or
%%% (at your option) any later version.
%%%
%%% SOD is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%%% GNU General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with SOD; if not, write to the Free Software Foundation,
%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

\chapter{C language utilities} \label{ch:clang}

%%%--------------------------------------------------------------------------
\section{C type representation} \label{sec:clang.c-types}

\subsection{Overview} \label{sec:clang.c-types.over}

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}.

\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|
  \end{tabbing}}
  \caption{Classes representing C types}
\label{fig:proto.c-types}
\end{figure}

C type objects are immutable unless otherwise specified.

\subsubsection{Constructing C type objects}
There is a constructor function for each non-abstract class of C type object.
Note, however, that constructor functions need not generate a fresh type
object if a previously existing type object is suitable.  In this case, we
say that the objects are \emph{interned}.  Some constructor functions are
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|.

The descriptions of each of the various classes include descriptions of the
initargs which may be passed to @|make-instance| when constructing a new
instance of the class.  However, the constructor functions and S-expression
syntax are strongly recommended over direct use of @|make-instance|.

\subsubsection{Printing}
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.
\end{itemize}
Neither generic function defines a default primary method; subclasses of
@|c-type| must define their own methods in order to print correctly.

\subsection{The C type root class} \label{sec:clang.c-types.root}

\begin{describe}{cls}{c-type ()}
  The class @|c-type| marks the root of the built-in C type hierarchy.

  Users may define subclasses of @|c-type|.  All non-abstract subclasses must
  have a primary method defined on @|pprint-c-type|; unless instances of the
  subclass are interned, a method on @|c-type-equal-p| is also required.

  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
type specifier.  Type specifiers fit into two syntactic categories.
\begin{itemize}
\item A \emph{symbolic type specifier} consists of a symbol.  It has a
  single, fixed meaning: if @<name> is a symbolic type specifier, then each
  use of @<name> in a type specifier evaluates to the same (@|eq|) type
  object, until the @<name> is redefined.
\item A \emph{type operator} is a symbol; the corresponding specifier is a
  list whose @|car| is the operator.  The remaining items in the list are
  arguments to the type operator.
\end{itemize}

\begin{describe}{mac}{c-type @<type-spec> @> @<c-type>}
  Evaluates to a C type object, as described by the type specifier
  @<type-spec>.
\end{describe}

\begin{describe}{mac}
    {defctype @{ @<name> @! (@<name> @<nickname>^*) @} @<type-spec>
      @> @<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>.

  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.
\end{describe}

\begin{describe}{mac}{c-type-alias @<original> @<alias>^* @> @<aliases>}
  Defines each @<alias> as being a type operator identical in behaviour to
  @<original>.  If @<original> is later redefined then the behaviour of the
  @<alias>es changes too.
\end{describe}

\begin{describe}{mac}
    {define-c-type-syntax @<name> @<lambda-list> @<form>^* @> @<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
  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 type specified by the arguments.

  The @<form>s may call @|expand-c-type-spec| in order to recursively expand
  type specifiers among its arguments.
\end{describe}

\begin{describe}{fun}{expand-c-type-spec @<type-spec> @> @<form>}
  Returns the Lisp form that @|(c-type @<type-spec>)| would expand into.
\end{describe}

\begin{describe}{gf}
    {print-c-type @<stream> @<type> \&optional @<colon> @<atsign>}
  Print the C type object @<type> to @<stream> in S-expression form.  The
  @<colon> and @<atsign> arguments may be interpreted in any way which seems
  appropriate: they are provided so that @|print-c-type| may be called via
  @|format|'s @|\char`\~/\dots/| command; they are not set when
  @|print-c-type| is called by Sod functions.

  There should be a method defined for every C type class; there is no
  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
argument lists for methods.  This is done by @|c-type-equal-p|.

\begin{describe}{gf}
    {c-type-equal-p @<c-type>_1 @<c-type>_2 @> @<generalized-boolean>}
  The generic function @|c-type-equal-p| compares two C types @<c-type>_1 and
  @<c-type>_2 for equality; it returns true if the two types are equal and
  false if they are not.

  Two types are equal if they are structurally similar, where this property
  is defined by methods for each individual class; see the descriptions of
  the classes for the details.

  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}
    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}
    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,
    this is a common case worth optimizing.
  \end{describe}
\end{describe}

\subsection{Outputting C types} \label{sec:clang.c-types.output}

\begin{describe}{gf}{pprint-c-type @<c-type> @<stream> @<kernel>}
  The generic function @|pprint-c-type| pretty-prints to @<stream> a C-syntax
  declaration of an object or function of type @<c-type>.  The result is
  written to @<stream>.

  A C declaration has two parts: a sequence of \emph{declaration specifiers}
  and a \emph{declarator}.  The declarator syntax involves parentheses and
  operators, in order to reflect the operators applicable to the declared
  variable.  For example, the name of a pointer variable is preceded by @`*';
  the name of an array is followed by dimensions enclosed in @`['\dots @`]'.

  The @<kernel> argument must be a function designator (though see the
  standard around-method); it is invoked as
  \begin{quote} \codeface
    (funcall @<kernel> @<stream> @<priority> @<spacep>)
  \end{quote}
  It should write to @<stream> -- which may not be the same stream originally
  passed into the generic function -- the `kernel' of the declarator, i.e.,
  the part to which prefix and/or postfix operators are attached to form the
  full declarator.

  The methods on @|pprint-c-type| specialized for compound types work by
  recursively calling @|pprint-c-type| on the subtype, passing down a closure
  which prints the necessary additional declarator operators before calling
  the original @<kernel> function.  The additional arguments @<priority> and
  @<spacep> support this implementation technique.

  The @<priority> argument describes the surrounding operator context.  It is
  zero if no type operators are directly attached to the kernel (i.e., there
  are no operators at all, or the kernel is enclosed in parentheses), one if
  a prefix operator is directly attached, or two if a postfix operator is
  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}).

  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}).

  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>}
    A default around method is defined on @|pprint-c-type| which `canonifies'
    non-function @<kernel> arguments.  In particular:
    \begin{itemize}
    \item if @<kernel> is nil, then @|pprint-c-type| is called recursively
      with a @<kernel> function that does nothing; and
    \item if @<kernel> is any other kind of object, then @|pprint-c-type| is
      called recursively with a @<kernel> function that prints the object as
      if by @|princ|, preceded if necessary by space using @|c-type-space|.
    \end{itemize}
  \end{describe}
\end{describe}

\begin{describe}{fun}{c-type-space @<stream>}
  Writes a space and other pretty-printing instructions to @<stream> in order
  visually to separate a declarator from the preceding declaration
  specifiers.  The precise details are subject to change.
\end{describe}

\begin{describe}{mac}
    {maybe-in-parens (@<stream-var> @<guard-form>) @<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
  the logical block has empty prefix and suffix strings; if it evaluates to a
  non-nil value, then the logical block has prefix and suffix @`(' and @`)'
  respectively.

  Note that this may cause @<stream> to be bound to a different stream object
  within the @<form>s.
\end{describe}

\subsection{Type qualifiers and qualifiable types}
\label{sec:clang.ctypes.qual}

\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|,
  @|restrict| and @|volatile|.

  The @<qualifiers> are a list of keyword symbols @|:const|, @|:restrict| and
  @|:volatile|.  There is no built-in limitation to these particular
  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.

  The class @|qualifiable-c-type| is abstract.
\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>}
  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
  bears the given @<qualifiers>.

  The @<c-type> is not modified.  If @<c-type> is interned, then the returned
  type will be interned.
\end{describe}

\begin{describe}{fun}{format-qualifiers @<qualifiers>}
  Returns a string containing the qualifiers listed in @<qualifiers> in C
  syntax, with a space after each.  In particular, if @<qualifiers> is
  non-null then the final character of the returned string will be a space.
\end{describe}

\subsection{Leaf types} \label{sec:clang.c-types.leaf}

A \emph{leaf type} is a type which is not defined in terms of another type.
In Sod, the leaf types are
\begin{itemize}
\item \emph{simple types}, including builtin types like @|int| and @|char|,
  as well as type names introduced by @|typename|, because Sod isn't
  interested in what the type name means, merely that it names a type; and
\item \emph{tagged types}, i.e., enum, struct and union types which are named
  by a keyword identifying the kind of type, and a \emph{tag}.
\end{itemize}

\begin{describe}{cls}{simple-c-type (qualifiable-c-type)
    \&key :qualifiers :name}
  The class of `simple types'; an instance denotes the type @<qualifiers>
  @<name>.

  A simple type object maintains a \emph{name}, which is a string whose
  contents are the C name for the type.  The initarg @|:name| may be used to
  provide this name when calling @|make-instance|.

  Two simple type objects are equal if and only if they have @|string=| names
  and matching qualifiers.

  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
  @|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}
    @|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}
    @|unsigned short|   & @|unsigned-short|, @|unsigned-short-int|,
                          @|ushort|                             \\ \hlx{vhv}
    @|int|              & @|int|, @|signed|, @|signed-int|,
                          @|sint|                               \\ \hlx{v}
    @|unsigned int|     & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{vhv}
    @|long|             & @|long|, @|signed-long|, @|long-int|,
                          @|signed-long-int|, @|slong|          \\ \hlx{v}
    @|unsigned long|    & @|unsigned-long|, @|unsigned-long-int|,
                          @|ulong|                              \\ \hlx{vhv}
    @|long long|        & @|long-long|, @|signed-long-long|,
                          @|long-long-int|,                     \\
                        & \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}
  \end{tabular}
  \caption{Builtin symbolic type specifiers for simple C types}
  \label{tab:proto.c-types.simple}
\end{table}

\begin{describe}{fun}
    {make-simple-type @<name> \&optional @<qualifiers> @> @<c-type>}
  Return the (unique interned) simple C type object for the C type whose name
  is @<name> (a string) and which has the given @<qualifiers> (a list of
  keywords).
\end{describe}

\begin{describe}{gf}{c-type-name @<c-type> @> @<string>}
  Returns the name of a @|simple-c-type| instance @<c-type> as an immutable
  string.
\end{describe}

\begin{describe}{mac}
    {define-simple-c-type @{ @<name> @! (@<name>^*) @} @<string> @> @<name>}
  Define type specifiers for a new simple C type.  Each symbol @<name> is
  defined as a symbolic type specifier for the (unique interned) simple C
  type whose name is the value of @<string>.  Further, each @<name> is
  defined to be a type operator: the type specifier @|(@<name>
  @<qualifier>^*)| evaluates to the (unique interned) simple C type whose
  name is @<string> and which has the @<qualifiers> (which are evaluated).
\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
  containing a C identifier.

  Two tagged types are equal if and only if they have the same class, their
  @<tag>s are @|string=|, and they have matching qualifiers.  (User-defined
  subclasses may have additional methods on @|c-type-equal-p| which impose
  further restrictions.)
\end{describe}
\begin{boxy}[Bug]
  Sod maintains distinct namespaces for the three kinds of tagged types.  In
  C, there is only one namespace for tags which is shared between enums,
  structs and unions.
\end{boxy}

\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|
  should return their own classification symbols.  It is intended that
  @|(string-downcase (c-tagged-type-kind @<c-type>))| be valid C
  syntax.\footnote{%
    Alas, C doesn't provide a syntactic category for these keywords;
    \Cplusplus\ calls them a @<class-key>.} %
  There is a method defined for each of the built-in tagged type classes
  @|c-struct-type|, @|c-union-type| and @|c-enum-type|.
\end{describe}

\begin{describe}{gf}{kind-c-tagged-type @<keyword> @> @<symbol>}
  This is not quite the inverse of @|c-tagged-type-kind|.  Given a keyword
  naming a kind of tagged type, return the name of the corresponding C
  type class as a symbol.
\end{describe}

\begin{describe}{cls}{c-enum-type (tagged-c-type) \&key :qualifiers :tag}
  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}
\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
  tag is @<tag> (a string) and which has the given @<qualifiers> (a list of
  keywords).
\end{describe}

\begin{describe}{cls}{c-struct-type (tagged-c-type) \&key :qualifiers :tag}
  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}
\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
  tag is @<tag> (a string) and which has the given @<qualifiers> (a list of
  keywords).
\end{describe}

\begin{describe}{cls}{c-union-type (tagged-c-type) \&key :qualifiers :tag}
  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}
\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
  is @<tag> (a string) and which has the given @<qualifiers> (a list of
  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
types.  The classes which represent compound types implement a common
protocol.

\begin{describe}{gf}{c-type-subtype @<c-type> @> @<subtype>}
  Returns the underlying type of a compound type @<c-type>.  Precisely what
  this means depends on the class of @<c-type>.
\end{describe}

\subsection{Pointer types} \label{sec:clang.c-types.pointer}

Pointers compound types.  The subtype of a pointer type is the type it points
to.

\begin{describe}{cls}
    {c-pointer-type (qualifiable-c-type) \&key :qualifiers :subtype}
  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 @`*'.

  The symbol @|string| is a type specifier for the type of pointer to
  characters; the symbol @|const-string| is a type specifier for the type
  pointer to constant characters.
\end{describe}

\begin{describe}{fun}
    {make-pointer-type @<c-type> \&optional @<qualifiers>
      @> @<c-pointer-type>}
  Return an object describing the type of qualified pointers 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.

\begin{describe}{cls}{c-array-type (c-type) \&key :subtype :dimensions}
  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
  individual dimension specifier is either a string containing a C integral
  constant expression, or nil which is equivalent to an empty string.  Only
  the first (outermost) dimension $d_0$ should be empty.

  C doesn't actually have multidimensional arrays as a primitive notion;
  rather, it permits an array (with known extent) to be the element type of
  an array, which achieves an equivalent effect.  C arrays are stored in
  row-major order: i.e., if we write down the indices of the elements of an
  array in order of ascending address, the rightmost index varies fastest;
  hence, the type constructed is more accurately an array of $d_0$ arrays of
  $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}

\begin{describe}{fun}
    {make-array-type @<subtype> @<dimensions> @> @<c-array-type>}
  Return an object describing the type of arrays with given @<dimensions> and
  with element type @<subtype> (an instance of @|c-type|).  The @<dimensions>
  argument is a list whose elements are strings or nil; see the description
  of the class @|c-array-type| above for details.
\end{describe}

\begin{describe}{gf}{c-array-dimensions @<c-type> @> @<list>}
  Returns the dimensions of @<c-type>, an array type, as an immutable list.
\end{describe}

\subsection{Function types} \label{sec:clang.c-types.fun}

\begin{describe}{cls}{argument}
\end{describe}

\begin{describe}{fun}{argumentp @<value> @> @<generalized-boolean>}
\end{describe}

\begin{describe}{fun}{make-argument @<name> @<c-type> @> @<argument>}
\end{describe}

\begin{describe}{fun}{argument-name @<argument> @> @<string>}
\end{describe}

\begin{describe}{fun}{argument-type @<argument> @> @<c-type>}
\end{describe}

\begin{describe}{fun}
    {commentify-argument-name @<name> @> @<commentified-name>}
\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
\end{describe}

\begin{describe}{fun}
    {c-function-arguments @<c-function-type> @> @<arguments>}
\end{describe}

\begin{describe}{fun}
    {make-c-type @<c-type> @<arguments> @> @<c-function-type>}
\end{describe}

\begin{describe}{fun}
    {commentify-argument-names @<arguments> @> @<commentified-arguments>}
\end{describe}

\begin{describe}{fun}
    {commentify-function-type @<c-type> @> @<commentified-c-type>}
\end{describe}

\subsection{Parsing C types} \label{sec:clang.c-types.parsing}

%%%--------------------------------------------------------------------------
\section{Generating C code} \label{sec:clang.codegen}

%%%----- That's all, folks --------------------------------------------------

%%% Local variables:
%%% mode: LaTeX
%%% TeX-master: "sod.tex"
%%% TeX-PDF-mode: t
%%% End:
