-(declaim (ftype (function (list policy) policy) process-optimize-declaration))
-(defun process-optimize-declaration (spec policy)
- (let ((res (copy-policy policy)))
- (dolist (quality (cdr spec))
- (let ((quality (if (atom quality) (list quality 3) quality)))
- (if (and (consp (cdr quality)) (null (cddr quality))
- (typep (second quality) 'real) (<= 0 (second quality) 3))
- (let ((value (rational (second quality))))
- (case (first quality)
- (speed (setf (policy-speed res) value))
- (space (setf (policy-space res) value))
- (safety (setf (policy-safety res) value))
- (compilation-speed (setf (policy-cspeed res) value))
- ;; FIXME: BREVITY is an undocumented name for it,
- ;; should go away. And INHIBIT-WARNINGS is a
- ;; misleading name for it. Perhaps BREVITY would be
- ;; better. But the ideal name would have connotations
- ;; of suppressing only optimization-related notes,
- ;; which I think is the behavior. Perhaps
- ;; INHIBIT-NOTES?
- ((inhibit-warnings brevity) (setf (policy-brevity res) value))
- ((debug-info debug) (setf (policy-debug res) value))
- (t
- (compiler-warning "unknown optimization quality ~S in ~S"
- (car quality) spec))))
- (compiler-warning
- "malformed optimization quality specifier ~S in ~S"
- quality spec))))
- res))
+(declaim (ftype (function (list policy) policy) process-optimize-decl))
+(defun process-optimize-decl (spec policy)
+ (let ((result nil))
+ ;; Add new entries from SPEC.
+ (dolist (q-and-v-or-just-q (cdr spec))
+ (multiple-value-bind (quality raw-value)
+ (if (atom q-and-v-or-just-q)
+ (values q-and-v-or-just-q 3)
+ (destructuring-bind (quality raw-value) q-and-v-or-just-q
+ (values quality raw-value)))
+ (cond ((not (policy-quality-name-p quality))
+ (compiler-warning "ignoring unknown optimization quality ~
+ ~S in ~S"
+ quality spec))
+ ((not (and (typep raw-value 'real) (<= 0 raw-value 3)))
+ (compiler-warning "ignoring bad optimization value ~S in ~S"
+ raw-value spec))
+ (t
+ (push (cons quality (rational raw-value))
+ result)))))
+ ;; Add any nonredundant entries from old POLICY.
+ (dolist (old-entry policy)
+ (unless (assq (car old-entry) result)
+ (push old-entry result)))
+ ;; Voila.
+ result))
+
+;;; ANSI defines the declaration (FOO X Y) to be equivalent to
+;;; (TYPE FOO X Y) when FOO is a type specifier. This function
+;;; implements that by converting (FOO X Y) to (TYPE FOO X Y).
+(defun canonized-decl-spec (decl-spec)
+ (let ((id (first decl-spec)))
+ (unless (symbolp id)
+ (error "The declaration identifier is not a symbol: ~S" id))
+ (let ((id-is-type (info :type :kind id))
+ (id-is-declared-decl (info :declaration :recognized id)))
+ (cond ((and id-is-type id-is-declared-decl)
+ (compiler-error
+ "ambiguous declaration ~S:~% ~
+ ~S was declared as a DECLARATION, but is also a type name."
+ decl-spec id))
+ (id-is-type
+ (cons 'type decl-spec))
+ (t
+ decl-spec)))))