From db56b1d3c3d4bc9ffb6500b1f40c27c77d868aa4 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Thu, 26 May 2016 09:26:09 +0100 Subject: [PATCH] src/c-types-impl.lisp, src/c-types-parse.lisp: Support C11 `_Alignas'. --- doc/SYMBOLS | 6 ++++++ doc/clang.tex | 9 +++++++++ doc/syntax.tex | 8 +++++++- src/c-types-impl.lisp | 20 ++++++++++++++++++++ src/c-types-parse.lisp | 15 +++++++++++++++ src/sod-module.5 | 17 +++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/doc/SYMBOLS b/doc/SYMBOLS index 022538a..20e2eef 100644 --- a/doc/SYMBOLS +++ b/doc/SYMBOLS @@ -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 diff --git a/doc/clang.tex b/doc/clang.tex index 5a22984..ce34265 100644 --- a/doc/clang.tex +++ b/doc/clang.tex @@ -465,6 +465,15 @@ complicated objects. @. \end{describe} +\begin{describe}{cls}{alignas-storage-specifier () \&key :alignment} + The class of @|_Alignas| storage specifiers; an instance denotes the + specifier @|_Alignas(@)|. The @ parameter may be any + printable object, but is usually a string or C fragment. + + The storage specifier form @|(alignas @)| returns a storage + specifier @|_Alignas(@)|, where @ is evaluated. +\end{describe} + \subsection{Leaf types} \label{sec:clang.c-types.leaf} diff --git a/doc/syntax.tex b/doc/syntax.tex index 560dc47..b8ae797 100644 --- a/doc/syntax.tex +++ b/doc/syntax.tex @@ -451,6 +451,7 @@ recognized. \alt "bool" | "_Bool" \alt "imaginary" | "_Imaginary" | "complex" | "_Complex" \alt +\alt \alt ::= | "const" | "volatile" | "restrict" @@ -460,6 +461,10 @@ recognized. ::= "atomic" | "_Atomic" + ::= "(" ")" + + ::= "alignas" "_Alignas" + ::= \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 @s, and one of the following, up to reordering. +more @s, zero or more @s, and one of the +following, up to reordering. \begin{itemize} \item @ \item @ diff --git a/src/c-types-impl.lisp b/src/c-types-impl.lisp index 719e610..97b6742 100644 --- a/src/c-types-impl.lisp +++ b/src/c-types-impl.lisp @@ -136,6 +136,26 @@ (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. diff --git a/src/c-types-parse.lisp b/src/c-types-parse.lisp index 94e8687..450cee6 100644 --- a/src/c-types-parse.lisp +++ b/src/c-types-parse.lisp @@ -288,6 +288,21 @@ #\)) (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. diff --git a/src/sod-module.5 b/src/sod-module.5 index 86b124d..1837524 100644 --- a/src/sod-module.5 +++ b/src/sod-module.5 @@ -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 -- 2.11.0