c-types-impl.lisp
cl:* variable function c-type
+ alignas
+ alignas-storage-specifier class
cl:array class c-type
atomic c-type
bool c-type
cl:t
sb-pcl::slot-object
cl:standard-object
+ alignas-storage-specifier
base-offset
sod::basic-codegen
codegen
cl:list
cl:symbol
expand-c-storage-specifier-form
+ (eql alignas) t
(eql sod-parser:lisp) t
expand-c-type-form
(eql cl:*) t
module
pprint-c-storage-specifier
cl:symbol t
+ alignas-storage-specifier t
pprint-c-type
t t t
c-array-type t t
print-c-storage-specifier
t cl:symbol
t t
+ t alignas-storage-specifier
print-c-type
t c-array-type
t c-atomic-type
@<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}
\alt "bool" | "_Bool"
\alt "imaginary" | "_Imaginary" | "complex" | "_Complex"
\alt <qualifier>
+\alt <storage-specifier>
\alt <atomic-type>
<qualifier> ::= <atomic> | "const" | "volatile" | "restrict"
<atomic> ::= "atomic" | "_Atomic"
+<storage-specifier> ::= <alignas> "(" <c-fragment> ")"
+
+<alignas> ::= "alignas" "_Alignas"
+
<type-name> ::= <identifier>
\end{grammar}
Declaration specifiers may appear in any order. However, not all
combinations are permitted. A declaration specifier must consist of zero or
-more @<qualifier>s, and one of the following, up to reordering.
+more @<qualifier>s, zero or more @<storage-specifier>s, and one of the
+following, up to reordering.
\begin{itemize}
\item @<type-name>
\item @<atomic-type>
,(expand-c-type-spec subtype)
(list ,@(mapcar #'expand-c-storage-specifier specifiers))))
+;;;--------------------------------------------------------------------------
+;;; Some storage specifiers.
+
+(export 'alignas-storage-specifier)
+(defclass alignas-storage-specifier ()
+ ((alignment :initarg :alignment :reader spec-alignment)))
+
+(export 'alignas)
+(define-c-storage-specifier-syntax alignas (alignment)
+ `(make-instance 'alignas-storage-specifier :alignment ,alignment))
+
+(defmethod print-c-storage-specifier
+ (stream (spec alignas-storage-specifier) &optional colon atsign)
+ (declare (ignore colon atsign))
+ (format stream "~:@<~S ~_~S~:>" 'alignas (spec-alignment spec)))
+
+(defmethod pprint-c-storage-specifier
+ ((spec alignas-storage-specifier) stream)
+ (format stream "_Alignas(~A)" (spec-alignment spec)))
+
;;;--------------------------------------------------------------------------
;;; Simple C types.
#\))
(make-atomic-type (car subtype)))))))
+(define-pluggable-parser complex-declspec alignas (scanner)
+ ;; `alignas' `(' fragment `)'
+ ;; `_Alignas' `(' fragment `)'
+ (with-parser-context (token-scanner-context :scanner scanner)
+ (parse (peek (seq ((nil (or "alignas" "_Alignas"))
+ (nil (lisp (values #\(
+ (eq (token-type scanner) #\()
+ nil)))
+ (nil (commit))
+ (frag (parse-delimited-fragment scanner #\( #\))))
+ (make-instance 'storespec
+ :spec (make-instance
+ 'alignas-storage-specifier
+ :alignment frag)))))))
+
(defun scan-and-merge-declspec (scanner specs)
"Scan a declaration specifier and merge it with SPECS.
.|
.I qualifier
.|
+.I storage-specifier
+.|
.I atomic-type
.br
.I qualifier
|
.B _Atomic
.br
+.I storage-specifier
+::=
+.I alignas
+.B (
+.I c-fragment
+.B )
+.br
+.I alignas
+::=
+.B alignas
+|
+.B _Alignas
+.br
.I type-name
::=
.I identifier
A declaration specifier must consist of
zero or more
.IR qualifier s,
+zero or more
+.IR storage-specifier s,
and one of the following, up to reordering.
.hP \*o
.I type-name