src/c-types-{impl,parse}.lisp: Support C11 `_Atomic'.
[sod] / src / c-types-impl.lisp
index be679a0..d0d4a74 100644 (file)
          (c-type-qualifiers type)))
 
 ;;;--------------------------------------------------------------------------
+;;; Atomic types.
+
+;; Class definition.
+
+(export 'c-atomic-type)
+(defclass c-atomic-type (qualifiable-c-type)
+  ((subtype :initarg :subtype :type c-type :reader c-type-subtype))
+  (:documentation "C atomic types."))
+
+;; Constructor function.
+
+(export 'make-atomic-type)
+(defun make-atomic-type (subtype &optional qualifiers)
+  "Return a (maybe distinguished) atomic type."
+  (make-or-intern-c-type 'c-atomic-type subtype
+                        :subtype subtype
+                        :qualifiers (canonify-qualifiers qualifiers)))
+
+;; Comparison protocol.
+
+(defmethod c-type-equal-p and ((type-a c-atomic-type) (type-b c-atomic-type))
+  (c-type-equal-p (c-type-subtype type-a) (c-type-subtype type-b)))
+
+;; C-syntax output protocol.
+
+(defmethod pprint-c-type ((type c-atomic-type) stream kernel)
+  (pprint-logical-block (stream nil)
+    (format stream "~{~A ~@_~}" (c-type-qualifier-keywords type))
+    (write-string "_Atomic(" stream)
+    (pprint-indent :current 0 stream)
+    (pprint-c-type (c-type-subtype type) stream
+                  (lambda (stream prio spacep)
+                    (declare (ignore stream prio spacep))))
+    (write-char #\) stream)))
+
+;; S-expression notation protocol.
+
+(defmethod print-c-type (stream (type c-atomic-type) &optional colon atsign)
+  (declare (ignore colon atsign))
+  (format stream "~:@<ATOMIC ~@_~/sod:print-c-type/~{ ~_~S~}~:>"
+         (c-type-subtype type)
+         (c-type-qualifiers type)))
+
+(export 'atomic)
+(define-c-type-syntax atomic (sub &rest quals)
+  "Return the type of atomic SUB."
+  `(make-atomic-type ,(expand-c-type-spec sub) (list ,@quals)))
+
+;;;--------------------------------------------------------------------------
 ;;; Pointer types.
 
 ;; Class definition.