+;; Let's not repeat ourselves.
+(macrolet ((define-declaration-specifiers (&rest defs)
+ (let ((mappings nil)
+ (deftypes nil)
+ (hashvar (gensym "HASH"))
+ (keyvar (gensym "KEY"))
+ (valvar (gensym "VAL")))
+ (dolist (def defs)
+ (destructuring-bind (kind &rest clauses) def
+ (let ((maps (mapcar (lambda (clause)
+ (if (consp clause)
+ clause
+ (cons (string-downcase clause)
+ clause)))
+ clauses)))
+ (push `(deftype ,(symbolicate 'decl- kind) ()
+ '(member ,@(mapcar #'cdr maps)))
+ deftypes)
+ (setf mappings (nconc (remove-if-not #'car maps)
+ mappings)))))
+ `(progn
+ ,@(nreverse deftypes)
+ (defparameter *declspec-map*
+ (let ((,hashvar (make-hash-table :test #'equal)))
+ (mapc (lambda (,keyvar ,valvar)
+ (setf (gethash ,keyvar ,hashvar) ,valvar))
+ ',(mapcar #'car mappings)
+ ',(mapcar #'cdr mappings))
+ ,hashvar))))))
+ (define-declaration-specifiers
+ (type :char :int :float :double :void)
+ (size :short :long (nil . :long-long))
+ (sign :signed :unsigned)
+ (qualifier :const :restrict :volatile)
+ (tagged :enum :struct :union)))
+