src/c-types-impl.lisp, src/c-types-parse.lisp: Support C11 `_Alignas'.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 26 May 2016 08:26:09 +0000 (09:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 29 May 2016 14:25:56 +0000 (15:25 +0100)
doc/SYMBOLS
doc/clang.tex
doc/syntax.tex
src/c-types-impl.lisp
src/c-types-parse.lisp
src/sod-module.5

index 022538a..20e2eef 100644 (file)
@@ -16,6 +16,8 @@ c-types-class-impl.lisp
 
 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
@@ -589,6 +591,7 @@ Classes:
 cl:t
   sb-pcl::slot-object
     cl:standard-object
+      alignas-storage-specifier
       base-offset
       sod::basic-codegen
         codegen
@@ -893,6 +896,7 @@ expand-c-storage-specifier
   cl:list
   cl:symbol
 expand-c-storage-specifier-form
+  (eql alignas) t
   (eql sod-parser:lisp) t
 expand-c-type-form
   (eql cl:*) t
@@ -1199,6 +1203,7 @@ module-pset
   module
 pprint-c-storage-specifier
   cl:symbol t
+  alignas-storage-specifier t
 pprint-c-type
   t t t
   c-array-type t t
@@ -1214,6 +1219,7 @@ primary-method-class
 print-c-storage-specifier
   t cl:symbol
   t t
+  t alignas-storage-specifier
 print-c-type
   t c-array-type
   t c-atomic-type
index 5a22984..ce34265 100644 (file)
@@ -465,6 +465,15 @@ complicated objects.
   @<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}
 
index 560dc47..b8ae797 100644 (file)
@@ -451,6 +451,7 @@ recognized.
 \alt "bool" | "_Bool"
 \alt "imaginary" | "_Imaginary" | "complex" | "_Complex"
 \alt <qualifier>
+\alt <storage-specifier>
 \alt <atomic-type>
 
 <qualifier> ::= <atomic> | "const" | "volatile" | "restrict"
@@ -460,6 +461,10 @@ recognized.
 
 <atomic> ::= "atomic" | "_Atomic"
 
+<storage-specifier> ::= <alignas> "(" <c-fragment> ")"
+
+<alignas> ::= "alignas" "_Alignas"
+
 <type-name> ::= <identifier>
 \end{grammar}
 
@@ -475,7 +480,8 @@ defined in the built-in module.
 
 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>
index 719e610..97b6742 100644 (file)
     (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.
 
 ;; Class definition.
index 94e8687..450cee6 100644 (file)
                       #\))
                   (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.
 
index 86b124d..1837524 100644 (file)
@@ -713,6 +713,8 @@ class-definition
 .|
 .I qualifier
 .|
+.I storage-specifier
+.|
 .I atomic-type
 .br
 .I qualifier
@@ -740,6 +742,19 @@ atomic
 |
 .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
@@ -761,6 +776,8 @@ However, not all combinations are permitted.
 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