src/c-types-{proto,impl,parse}.lisp: Add `storage specifiers' to the model.
[sod] / src / c-types-impl.lisp
index d0d4a74..719e610 100644 (file)
           initargs)))
 
 ;;;--------------------------------------------------------------------------
+;;; Storage specifiers.
+
+(defmethod c-type-equal-p :around
+    ((type-a c-storage-specifiers-type) (type-b c-type))
+  "Ignore storage specifiers when comparing C types."
+  (c-type-equal-p (c-type-subtype type-a) type-b))
+
+(defmethod c-type-equal-p :around
+    ((type-a c-type) (type-b c-storage-specifiers-type))
+  "Ignore storage specifiers when comparing C types."
+  (c-type-equal-p type-a (c-type-subtype type-b)))
+
+(defun make-storage-specifiers-type (subtype specifiers)
+  "Construct a type based on SUBTYPE, carrying the storage SPECIFIERS."
+  (if (null specifiers) subtype
+      (make-or-intern-c-type 'c-storage-specifiers-type subtype
+                            :specifiers specifiers
+                            :subtype subtype)))
+
+(defmethod pprint-c-type ((type c-storage-specifiers-type) stream kernel)
+  (dolist (spec (c-type-specifiers type))
+    (pprint-c-storage-specifier spec stream)
+    (write-char #\space stream)
+    (pprint-newline :miser stream))
+  (pprint-c-type (c-type-subtype type) stream kernel))
+
+(defmethod print-c-type
+    (stream (type c-storage-specifiers-type) &optional colon atsign)
+  (declare (ignore colon atsign))
+  (format stream "~:@<SPECS ~@_~:I~/sod:print-c-type/~
+                           ~{ ~_~/sod:print-c-storage-specifier/~}~:>"
+         (c-type-subtype type) (c-type-specifiers type)))
+
+(export 'specs)
+(define-c-type-syntax specs (subtype &rest specifiers)
+  `(make-storage-specifiers-type
+    ,(expand-c-type-spec subtype)
+    (list ,@(mapcar #'expand-c-storage-specifier specifiers))))
+
+;;;--------------------------------------------------------------------------
 ;;; Simple C types.
 
 ;; Class definition.