src/c-types-{proto,impl,parse}.lisp: Add `storage specifiers' to the model.
[sod] / doc / clang.tex
index 348c5b6..5a22984 100644 (file)
@@ -385,6 +385,87 @@ methods to \descref{c-qualifier-keyword}{gf}.
 \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{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}
+
+
 \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.