Line data Source code
1 : ;;; byte-run.el --- byte-compiler support for inlining -*- lexical-binding: t -*-
2 :
3 : ;; Copyright (C) 1992, 2001-2017 Free Software Foundation, Inc.
4 :
5 : ;; Author: Jamie Zawinski <jwz@lucid.com>
6 : ;; Hallvard Furuseth <hbf@ulrik.uio.no>
7 : ;; Maintainer: emacs-devel@gnu.org
8 : ;; Keywords: internal
9 : ;; Package: emacs
10 :
11 : ;; This file is part of GNU Emacs.
12 :
13 : ;; GNU Emacs is free software: you can redistribute it and/or modify
14 : ;; it under the terms of the GNU General Public License as published by
15 : ;; the Free Software Foundation, either version 3 of the License, or
16 : ;; (at your option) any later version.
17 :
18 : ;; GNU Emacs is distributed in the hope that it will be useful,
19 : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : ;; GNU General Public License for more details.
22 :
23 : ;; You should have received a copy of the GNU General Public License
24 : ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 :
26 : ;;; Commentary:
27 :
28 : ;; interface to selectively inlining functions.
29 : ;; This only happens when source-code optimization is turned on.
30 :
31 : ;;; Code:
32 :
33 : (defalias 'function-put
34 : ;; We don't want people to just use `put' because we can't conveniently
35 : ;; hook into `put' to remap old properties to new ones. But for now, there's
36 : ;; no such remapping, so we just call `put'.
37 : #'(lambda (function prop value)
38 : "Set FUNCTION's property PROP to VALUE.
39 : The namespace for PROP is shared with symbols.
40 : So far, FUNCTION can only be a symbol, not a lambda expression."
41 : (put function prop value)))
42 : (function-put 'defmacro 'doc-string-elt 3)
43 : (function-put 'defmacro 'lisp-indent-function 2)
44 :
45 : ;; `macro-declaration-function' are both obsolete (as marked at the end of this
46 : ;; file) but used in many .elc files.
47 :
48 : (defvar macro-declaration-function #'macro-declaration-function
49 : "Function to process declarations in a macro definition.
50 : The function will be called with two args MACRO and DECL.
51 : MACRO is the name of the macro being defined.
52 : DECL is a list `(declare ...)' containing the declarations.
53 : The value the function returns is not used.")
54 :
55 : (defalias 'macro-declaration-function
56 : #'(lambda (macro decl)
57 : "Process a declaration found in a macro definition.
58 : This is set as the value of the variable `macro-declaration-function'.
59 : MACRO is the name of the macro being defined.
60 : DECL is a list `(declare ...)' containing the declarations.
61 : The return value of this function is not used."
62 : ;; We can't use `dolist' or `cadr' yet for bootstrapping reasons.
63 : (let (d)
64 : ;; Ignore the first element of `decl' (it's always `declare').
65 : (while (setq decl (cdr decl))
66 : (setq d (car decl))
67 : (if (and (consp d)
68 : (listp (cdr d))
69 : (null (cdr (cdr d))))
70 : (cond ((eq (car d) 'indent)
71 : (put macro 'lisp-indent-function (car (cdr d))))
72 : ((eq (car d) 'debug)
73 : (put macro 'edebug-form-spec (car (cdr d))))
74 : ((eq (car d) 'doc-string)
75 : (put macro 'doc-string-elt (car (cdr d))))
76 : (t
77 : (message "Unknown declaration %s" d)))
78 : (message "Invalid declaration %s" d))))))
79 :
80 : ;; We define macro-declaration-alist here because it is needed to
81 : ;; handle declarations in macro definitions and this is the first file
82 : ;; loaded by loadup.el that uses declarations in macros.
83 :
84 : ;; Add any new entries to info node `(elisp)Declare Form'.
85 : (defvar defun-declarations-alist
86 : (list
87 : ;; We can only use backquotes inside the lambdas and not for those
88 : ;; properties that are used by functions loaded before backquote.el.
89 : (list 'advertised-calling-convention
90 : #'(lambda (f _args arglist when)
91 : (list 'set-advertised-calling-convention
92 : (list 'quote f) (list 'quote arglist) (list 'quote when))))
93 : (list 'obsolete
94 : #'(lambda (f _args new-name when)
95 : (list 'make-obsolete
96 : (list 'quote f) (list 'quote new-name) (list 'quote when))))
97 : (list 'interactive-only
98 : #'(lambda (f _args instead)
99 : (list 'function-put (list 'quote f)
100 : ''interactive-only (list 'quote instead))))
101 : ;; FIXME: Merge `pure' and `side-effect-free'.
102 : (list 'pure
103 : #'(lambda (f _args val)
104 : (list 'function-put (list 'quote f)
105 : ''pure (list 'quote val)))
106 : "If non-nil, the compiler can replace calls with their return value.
107 : This may shift errors from run-time to compile-time.")
108 : (list 'side-effect-free
109 : #'(lambda (f _args val)
110 : (list 'function-put (list 'quote f)
111 : ''side-effect-free (list 'quote val)))
112 : "If non-nil, calls can be ignored if their value is unused.
113 : If `error-free', drop calls even if `byte-compile-delete-errors' is nil.")
114 : (list 'compiler-macro
115 : #'(lambda (f args compiler-function)
116 : (if (not (eq (car-safe compiler-function) 'lambda))
117 : `(eval-and-compile
118 : (function-put ',f 'compiler-macro #',compiler-function))
119 : (let ((cfname (intern (concat (symbol-name f) "--anon-cmacro"))))
120 : `(progn
121 : (eval-and-compile
122 : (function-put ',f 'compiler-macro #',cfname))
123 : ;; Don't autoload the compiler-macro itself, since the
124 : ;; macroexpander will find this file via `f's autoload,
125 : ;; if needed.
126 : :autoload-end
127 : (eval-and-compile
128 : (defun ,cfname (,@(cadr compiler-function) ,@args)
129 : ,@(cddr compiler-function))))))))
130 : (list 'doc-string
131 : #'(lambda (f _args pos)
132 : (list 'function-put (list 'quote f)
133 : ''doc-string-elt (list 'quote pos))))
134 : (list 'indent
135 : #'(lambda (f _args val)
136 : (list 'function-put (list 'quote f)
137 : ''lisp-indent-function (list 'quote val)))))
138 : "List associating function properties to their macro expansion.
139 : Each element of the list takes the form (PROP FUN) where FUN is
140 : a function. For each (PROP . VALUES) in a function's declaration,
141 : the FUN corresponding to PROP is called with the function name,
142 : the function's arglist, and the VALUES and should return the code to use
143 : to set this property.
144 :
145 : This is used by `declare'.")
146 :
147 : (defvar macro-declarations-alist
148 : (cons
149 : (list 'debug
150 : #'(lambda (name _args spec)
151 : (list 'progn :autoload-end
152 : (list 'put (list 'quote name)
153 : ''edebug-form-spec (list 'quote spec)))))
154 : (cons
155 : (list 'no-font-lock-keyword
156 : #'(lambda (name _args val)
157 : (list 'function-put (list 'quote name)
158 : ''no-font-lock-keyword (list 'quote val))))
159 : defun-declarations-alist))
160 : "List associating properties of macros to their macro expansion.
161 : Each element of the list takes the form (PROP FUN) where FUN is a function.
162 : For each (PROP . VALUES) in a macro's declaration, the FUN corresponding
163 : to PROP is called with the macro name, the macro's arglist, and the VALUES
164 : and should return the code to use to set this property.
165 :
166 : This is used by `declare'.")
167 :
168 : (defalias 'defmacro
169 : (cons
170 : 'macro
171 : #'(lambda (name arglist &optional docstring &rest body)
172 : "Define NAME as a macro.
173 : When the macro is called, as in (NAME ARGS...),
174 : the function (lambda ARGLIST BODY...) is applied to
175 : the list ARGS... as it appears in the expression,
176 : and the result should be a form to be evaluated instead of the original.
177 : DECL is a declaration, optional, of the form (declare DECLS...) where
178 : DECLS is a list of elements of the form (PROP . VALUES). These are
179 : interpreted according to `macro-declarations-alist'.
180 : The return value is undefined.
181 :
182 : \(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)"
183 : ;; We can't just have `decl' as an &optional argument, because we need
184 : ;; to distinguish
185 : ;; (defmacro foo (arg) (bar) nil)
186 : ;; from
187 : ;; (defmacro foo (arg) (bar)).
188 : (let ((decls (cond
189 : ((eq (car-safe docstring) 'declare)
190 : (prog1 (cdr docstring) (setq docstring nil)))
191 : ((and (stringp docstring)
192 : (eq (car-safe (car body)) 'declare))
193 : (prog1 (cdr (car body)) (setq body (cdr body)))))))
194 : (if docstring (setq body (cons docstring body))
195 : (if (null body) (setq body '(nil))))
196 : ;; Can't use backquote because it's not defined yet!
197 : (let* ((fun (list 'function (cons 'lambda (cons arglist body))))
198 : (def (list 'defalias
199 : (list 'quote name)
200 : (list 'cons ''macro fun)))
201 : (declarations
202 : (mapcar
203 : #'(lambda (x)
204 : (let ((f (cdr (assq (car x) macro-declarations-alist))))
205 : (if f (apply (car f) name arglist (cdr x))
206 : (message "Warning: Unknown macro property %S in %S"
207 : (car x) name))))
208 : decls)))
209 : ;; Refresh font-lock if this is a new macro, or it is an
210 : ;; existing macro whose 'no-font-lock-keyword declaration
211 : ;; has changed.
212 : (if (and
213 : ;; If lisp-mode hasn't been loaded, there's no reason
214 : ;; to flush.
215 : (fboundp 'lisp--el-font-lock-flush-elisp-buffers)
216 : (or (not (fboundp name)) ;; new macro
217 : (and (fboundp name) ;; existing macro
218 : (member `(function-put ',name 'no-font-lock-keyword
219 : ',(get name 'no-font-lock-keyword))
220 : declarations))))
221 : (lisp--el-font-lock-flush-elisp-buffers))
222 : (if declarations
223 : (cons 'prog1 (cons def declarations))
224 : def))))))
225 :
226 : ;; Now that we defined defmacro we can use it!
227 : (defmacro defun (name arglist &optional docstring &rest body)
228 : "Define NAME as a function.
229 : The definition is (lambda ARGLIST [DOCSTRING] BODY...).
230 : See also the function `interactive'.
231 : DECL is a declaration, optional, of the form (declare DECLS...) where
232 : DECLS is a list of elements of the form (PROP . VALUES). These are
233 : interpreted according to `defun-declarations-alist'.
234 : The return value is undefined.
235 :
236 : \(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)"
237 : ;; We can't just have `decl' as an &optional argument, because we need
238 : ;; to distinguish
239 : ;; (defun foo (arg) (toto) nil)
240 : ;; from
241 : ;; (defun foo (arg) (toto)).
242 : (declare (doc-string 3) (indent 2))
243 5876 : (or name (error "Cannot define '%s' as a function" name))
244 5876 : (if (null
245 5876 : (and (listp arglist)
246 5876 : (null (delq t (mapcar #'symbolp arglist)))))
247 5876 : (error "Malformed arglist: %s" arglist))
248 5876 : (let ((decls (cond
249 5876 : ((eq (car-safe docstring) 'declare)
250 36 : (prog1 (cdr docstring) (setq docstring nil)))
251 5840 : ((and (stringp docstring)
252 5840 : (eq (car-safe (car body)) 'declare))
253 5876 : (prog1 (cdr (car body)) (setq body (cdr body)))))))
254 5876 : (if docstring (setq body (cons docstring body))
255 5876 : (if (null body) (setq body '(nil))))
256 5876 : (let ((declarations
257 5876 : (mapcar
258 5876 : #'(lambda (x)
259 328 : (let ((f (cdr (assq (car x) defun-declarations-alist))))
260 328 : (cond
261 328 : (f (apply (car f) name arglist (cdr x)))
262 : ;; Yuck!!
263 0 : ((and (featurep 'cl)
264 0 : (memq (car x) ;C.f. cl-do-proclaim.
265 0 : '(special inline notinline optimize warn)))
266 0 : (push (list 'declare x)
267 0 : (if (stringp docstring)
268 0 : (if (eq (car-safe (cadr body)) 'interactive)
269 0 : (cddr body)
270 0 : (cdr body))
271 0 : (if (eq (car-safe (car body)) 'interactive)
272 0 : (cdr body)
273 0 : body)))
274 : nil)
275 0 : (t (message "Warning: Unknown defun property `%S' in %S"
276 6204 : (car x) name)))))
277 5876 : decls))
278 5876 : (def (list 'defalias
279 5876 : (list 'quote name)
280 5876 : (list 'function
281 5876 : (cons 'lambda
282 5876 : (cons arglist body))))))
283 5876 : (if declarations
284 326 : (cons 'prog1 (cons def declarations))
285 5876 : def))))
286 :
287 :
288 : ;; Redefined in byte-optimize.el.
289 : ;; This is not documented--it's not clear that we should promote it.
290 : (fset 'inline 'progn)
291 :
292 : ;;; Interface to inline functions.
293 :
294 : ;; (defmacro proclaim-inline (&rest fns)
295 : ;; "Cause the named functions to be open-coded when called from compiled code.
296 : ;; They will only be compiled open-coded when byte-compile-optimize is true."
297 : ;; (cons 'eval-and-compile
298 : ;; (mapcar (lambda (x)
299 : ;; (or (memq (get x 'byte-optimizer)
300 : ;; '(nil byte-compile-inline-expand))
301 : ;; (error
302 : ;; "%s already has a byte-optimizer, can't make it inline"
303 : ;; x))
304 : ;; (list 'put (list 'quote x)
305 : ;; ''byte-optimizer ''byte-compile-inline-expand))
306 : ;; fns)))
307 :
308 : ;; (defmacro proclaim-notinline (&rest fns)
309 : ;; "Cause the named functions to no longer be open-coded."
310 : ;; (cons 'eval-and-compile
311 : ;; (mapcar (lambda (x)
312 : ;; (if (eq (get x 'byte-optimizer) 'byte-compile-inline-expand)
313 : ;; (put x 'byte-optimizer nil))
314 : ;; (list 'if (list 'eq (list 'get (list 'quote x) ''byte-optimizer)
315 : ;; ''byte-compile-inline-expand)
316 : ;; (list 'put x ''byte-optimizer nil)))
317 : ;; fns)))
318 :
319 : (defmacro defsubst (name arglist &rest body)
320 : "Define an inline function. The syntax is just like that of `defun'.
321 : \(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)"
322 : (declare (debug defun) (doc-string 3))
323 163 : (or (memq (get name 'byte-optimizer)
324 163 : '(nil byte-compile-inline-expand))
325 163 : (error "`%s' is a primitive" name))
326 163 : `(prog1
327 163 : (defun ,name ,arglist ,@body)
328 : (eval-and-compile
329 163 : (put ',name 'byte-optimizer 'byte-compile-inline-expand))))
330 :
331 : (defvar advertised-signature-table (make-hash-table :test 'eq :weakness 'key))
332 :
333 : (defun set-advertised-calling-convention (function signature _when)
334 : "Set the advertised SIGNATURE of FUNCTION.
335 : This will allow the byte-compiler to warn the programmer when she uses
336 : an obsolete calling convention. WHEN specifies since when the calling
337 : convention was modified."
338 10 : (puthash (indirect-function function) signature
339 10 : advertised-signature-table))
340 :
341 : (defun make-obsolete (obsolete-name current-name &optional when)
342 : "Make the byte-compiler warn that function OBSOLETE-NAME is obsolete.
343 : OBSOLETE-NAME should be a function name or macro name (a symbol).
344 :
345 : The warning will say that CURRENT-NAME should be used instead.
346 : If CURRENT-NAME is a string, that is the `use instead' message
347 : \(it should end with a period, and not start with a capital).
348 : WHEN should be a string indicating when the function
349 : was first made obsolete, for example a date or a release number."
350 : (declare (advertised-calling-convention
351 : ;; New code should always provide the `when' argument.
352 : (obsolete-name current-name when) "23.1"))
353 247 : (put obsolete-name 'byte-obsolete-info
354 : ;; The second entry used to hold the `byte-compile' handler, but
355 : ;; is not used any more nowadays.
356 247 : (purecopy (list current-name nil when)))
357 247 : obsolete-name)
358 :
359 : (defmacro define-obsolete-function-alias (obsolete-name current-name
360 : &optional when docstring)
361 : "Set OBSOLETE-NAME's function definition to CURRENT-NAME and mark it obsolete.
362 :
363 : \(define-obsolete-function-alias \\='old-fun \\='new-fun \"22.1\" \"old-fun's doc.\")
364 :
365 : is equivalent to the following two lines of code:
366 :
367 : \(defalias \\='old-fun \\='new-fun \"old-fun's doc.\")
368 : \(make-obsolete \\='old-fun \\='new-fun \"22.1\")
369 :
370 : If provided, WHEN should be a string indicating when the function
371 : was first made obsolete, for example a date or a release number.
372 :
373 : See the docstrings of `defalias' and `make-obsolete' for more details."
374 : (declare (doc-string 4)
375 : (advertised-calling-convention
376 : ;; New code should always provide the `when' argument.
377 : (obsolete-name current-name when &optional docstring) "23.1"))
378 68 : `(progn
379 68 : (defalias ,obsolete-name ,current-name ,docstring)
380 68 : (make-obsolete ,obsolete-name ,current-name ,when)))
381 :
382 : (defun make-obsolete-variable (obsolete-name current-name &optional when access-type)
383 : "Make the byte-compiler warn that OBSOLETE-NAME is obsolete.
384 : The warning will say that CURRENT-NAME should be used instead.
385 : If CURRENT-NAME is a string, that is the `use instead' message.
386 : WHEN should be a string indicating when the variable
387 : was first made obsolete, for example a date or a release number.
388 : ACCESS-TYPE if non-nil should specify the kind of access that will trigger
389 : obsolescence warnings; it can be either `get' or `set'."
390 : (declare (advertised-calling-convention
391 : ;; New code should always provide the `when' argument.
392 : (obsolete-name current-name when &optional access-type) "23.1"))
393 117 : (put obsolete-name 'byte-obsolete-variable
394 117 : (purecopy (list current-name access-type when)))
395 117 : obsolete-name)
396 :
397 :
398 : (defmacro define-obsolete-variable-alias (obsolete-name current-name
399 : &optional when docstring)
400 : "Make OBSOLETE-NAME a variable alias for CURRENT-NAME and mark it obsolete.
401 : This uses `defvaralias' and `make-obsolete-variable' (which see).
402 : See the Info node `(elisp)Variable Aliases' for more details.
403 :
404 : If CURRENT-NAME is a defcustom or a defvar (more generally, any variable
405 : where OBSOLETE-NAME may be set, e.g. in an init file, before the
406 : alias is defined), then the define-obsolete-variable-alias
407 : statement should be evaluated before the defcustom, if user
408 : customizations are to be respected. The simplest way to achieve
409 : this is to place the alias statement before the defcustom (this
410 : is not necessary for aliases that are autoloaded, or in files
411 : dumped with Emacs). This is so that any user customizations are
412 : applied before the defcustom tries to initialize the
413 : variable (this is due to the way `defvaralias' works).
414 :
415 : If provided, WHEN should be a string indicating when the variable
416 : was first made obsolete, for example a date or a release number.
417 :
418 : For the benefit of `custom-set-variables', if OBSOLETE-NAME has
419 : any of the following properties, they are copied to
420 : CURRENT-NAME, if it does not already have them:
421 : `saved-value', `saved-variable-comment'."
422 : (declare (doc-string 4)
423 : (advertised-calling-convention
424 : ;; New code should always provide the `when' argument.
425 : (obsolete-name current-name when &optional docstring) "23.1"))
426 38 : `(progn
427 38 : (defvaralias ,obsolete-name ,current-name ,docstring)
428 : ;; See Bug#4706.
429 : (dolist (prop '(saved-value saved-variable-comment))
430 38 : (and (get ,obsolete-name prop)
431 38 : (null (get ,current-name prop))
432 38 : (put ,current-name prop (get ,obsolete-name prop))))
433 38 : (make-obsolete-variable ,obsolete-name ,current-name ,when)))
434 :
435 : ;; FIXME This is only defined in this file because the variable- and
436 : ;; function- versions are too. Unlike those two, this one is not used
437 : ;; by the byte-compiler (would be nice if it could warn about obsolete
438 : ;; faces, but it doesn't really do anything special with faces).
439 : ;; It only really affects M-x describe-face output.
440 : (defmacro define-obsolete-face-alias (obsolete-face current-face when)
441 : "Make OBSOLETE-FACE a face alias for CURRENT-FACE and mark it obsolete.
442 : If provided, WHEN should be a string indicating when the face
443 : was first made obsolete, for example a date or a release number."
444 0 : `(progn
445 0 : (put ,obsolete-face 'face-alias ,current-face)
446 : ;; Used by M-x describe-face.
447 0 : (put ,obsolete-face 'obsolete-face (or (purecopy ,when) t))))
448 :
449 : (defmacro dont-compile (&rest body)
450 : "Like `progn', but the body always runs interpreted (not compiled).
451 : If you think you need this, you're probably making a mistake somewhere."
452 : (declare (debug t) (indent 0) (obsolete nil "24.4"))
453 0 : (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body)))))
454 :
455 :
456 : ;; interface to evaluating things at compile time and/or load time
457 : ;; these macro must come after any uses of them in this file, as their
458 : ;; definition in the file overrides the magic definitions on the
459 : ;; byte-compile-macro-environment.
460 :
461 : (defmacro eval-when-compile (&rest body)
462 : "Like `progn', but evaluates the body at compile time if you're compiling.
463 : Thus, the result of the body appears to the compiler as a quoted
464 : constant. In interpreted code, this is entirely equivalent to
465 : `progn', except that the value of the expression may be (but is
466 : not necessarily) computed at load time if eager macro expansion
467 : is enabled."
468 : (declare (debug (&rest def-form)) (indent 0))
469 91 : (list 'quote (eval (cons 'progn body) lexical-binding)))
470 :
471 : (defmacro eval-and-compile (&rest body)
472 : "Like `progn', but evaluates the body at compile time and at
473 : load time. In interpreted code, this is entirely equivalent to
474 : `progn', except that the value of the expression may be (but is
475 : not necessarily) computed at load time if eager macro expansion
476 : is enabled."
477 : (declare (debug (&rest def-form)) (indent 0))
478 : ;; When the byte-compiler expands code, this macro is not used, so we're
479 : ;; either about to run `body' (plain interpretation) or we're doing eager
480 : ;; macroexpansion.
481 478 : (list 'quote (eval (cons 'progn body) lexical-binding)))
482 :
483 : (defun with-no-warnings (&rest body)
484 : "Like `progn', but prevents compiler warnings in the body."
485 : (declare (indent 0))
486 : ;; The implementation for the interpreter is basically trivial.
487 65600 : (car (last body)))
488 :
489 :
490 : ;; I nuked this because it's not a good idea for users to think of using it.
491 : ;; These options are a matter of installation preference, and have nothing to
492 : ;; with particular source files; it's a mistake to suggest to users
493 : ;; they should associate these with particular source files.
494 : ;; There is hardly any reason to change these parameters, anyway.
495 : ;; --rms.
496 :
497 : ;; (put 'byte-compiler-options 'lisp-indent-function 0)
498 : ;; (defmacro byte-compiler-options (&rest args)
499 : ;; "Set some compilation-parameters for this file. This will affect only the
500 : ;; file in which it appears; this does nothing when evaluated, and when loaded
501 : ;; from a .el file.
502 : ;;
503 : ;; Each argument to this macro must be a list of a key and a value.
504 : ;;
505 : ;; Keys: Values: Corresponding variable:
506 : ;;
507 : ;; verbose t, nil byte-compile-verbose
508 : ;; optimize t, nil, source, byte byte-compile-optimize
509 : ;; warnings list of warnings byte-compile-warnings
510 : ;; Valid elements: (callargs redefine free-vars unresolved)
511 : ;; file-format emacs18, emacs19 byte-compile-compatibility
512 : ;;
513 : ;; For example, this might appear at the top of a source file:
514 : ;;
515 : ;; (byte-compiler-options
516 : ;; (optimize t)
517 : ;; (warnings (- free-vars)) ; Don't warn about free variables
518 : ;; (file-format emacs19))"
519 : ;; nil)
520 :
521 : (make-obsolete-variable 'macro-declaration-function
522 : 'macro-declarations-alist "24.3")
523 : (make-obsolete 'macro-declaration-function
524 : 'macro-declarations-alist "24.3")
525 :
526 : ;;; byte-run.el ends here
|