summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-bytecomp.el
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2015-01-13 15:39:36 +0000
committerAlan Mackenzie <acm@muc.de>2015-01-13 15:47:26 +0000
commit30c5f5cdef8db72c007efecfc8436479631b45d0 (patch)
tree781d6e630b7efca6e0fef929a416bb79851949f5 /lisp/progmodes/cc-bytecomp.el
parentc3024739131467b607fa745daf52ca25a3fd3c4d (diff)
Allow compilation during loading of Modes derived from a CC Mode mode.
Fixes debbugs#19206. cc-bytecomp.el (cc-bytecomp-compiling-or-loading): new function which walks the stack to discover whether we're compiling or loading. (cc-bytecomp-is-compiling): Reformulate, and move towards beginning. (cc-bytecomp-is-loading): New defsubst. (cc-bytecomp-setup-environment, cc-bytecomp-restore-environment): Use the above defsubsts. (cc-require-when-compile, cc-bytecomp-defvar) (cc-bytecomp-defun): Simplify conditionals. cc-defs.el (cc-bytecomp-compiling-or-loading): "Borrow" this function from cc-bytecomp.el. (c-get-current-file): Reformulate using the above. (c-lang-defconst): Prevent duplicate entries of file names in a symbol's 'source property. (c-lang-const): Use cc-bytecomp-is-compiling. cc-langs.el (c-make-init-lang-vars-fun): Use cc-bytecomp-is-compiling.
Diffstat (limited to 'lisp/progmodes/cc-bytecomp.el')
-rw-r--r--lisp/progmodes/cc-bytecomp.el72
1 files changed, 55 insertions, 17 deletions
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index bf7803c85ca..b63eeb4c7a6 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -89,13 +89,60 @@
;;`(message ,@args)
)
+(defun cc-bytecomp-compiling-or-loading ()
+ ;; Determine whether byte-compilation or loading is currently active,
+ ;; returning 'compiling, 'loading or nil.
+ ;; If both are active, the "innermost" activity counts. Note that
+ ;; compilation can trigger loading (various `require' type forms)
+ ;; and loading can trigger compilation (the package manager does
+ ;; this). We walk the lisp stack if necessary.
+ (cond
+ ((and load-in-progress
+ (boundp 'byte-compile-dest-file)
+ (stringp byte-compile-dest-file))
+ (let ((n 0) elt)
+ (while (and
+ (setq elt (backtrace-frame n))
+ (not (and (car elt)
+ (memq (cadr elt)
+ '(load require
+ byte-compile-file byte-recompile-directory
+ batch-byte-compile)))))
+ (setq n (1+ n)))
+ (cond
+ ((memq (cadr elt) '(load require))
+ 'loading)
+ ((memq (cadr elt) '(byte-compile-file
+ byte-recompile-directory
+ batch-byte-compile))
+ 'compiling)
+ (t ; Can't happen.
+ (message "cc-bytecomp-compiling-or-loading: System flags spuriously set")
+ nil))))
+ (load-in-progress
+ ;; Being loaded.
+ 'loading)
+ ((and (boundp 'byte-compile-dest-file)
+ (stringp byte-compile-dest-file))
+ ;; Being compiled.
+ 'compiling)
+ (t
+ ;; Being evaluated interactively.
+ nil)))
+
+(defsubst cc-bytecomp-is-compiling ()
+ "Return non-nil if eval'ed during compilation."
+ (eq (cc-bytecomp-compiling-or-loading) 'compiling))
+
+(defsubst cc-bytecomp-is-loading ()
+ "Return non-nil if eval'ed during loading.
+Nil will be returned if we're in a compilation triggered by the loading."
+ (eq (cc-bytecomp-compiling-or-loading) 'loading))
+
(defun cc-bytecomp-setup-environment ()
;; Eval'ed during compilation to setup variables, functions etc
;; declared with `cc-bytecomp-defvar' et al.
- (if (not load-in-progress)
- ;; Look at `load-in-progress' to tell whether we're called
- ;; directly in the file being compiled or just from some file
- ;; being loaded during compilation.
+ (if (not (cc-bytecomp-is-loading))
(let (p)
(if cc-bytecomp-environment-set
(error "Byte compilation environment already set - \
@@ -143,7 +190,7 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
(defun cc-bytecomp-restore-environment ()
;; Eval'ed during compilation to restore variables, functions etc
;; declared with `cc-bytecomp-defvar' et al.
- (if (not load-in-progress)
+ (if (not (cc-bytecomp-is-loading))
(let (p)
(setq p cc-bytecomp-unbound-variables)
(while p
@@ -287,8 +334,7 @@ use within `eval-when-compile'."
`(eval-when-compile
(if (and (fboundp 'cc-bytecomp-is-compiling)
(cc-bytecomp-is-compiling))
- (if (or (not load-in-progress)
- (not (featurep ,cc-part)))
+ (if (not (featurep ,cc-part))
(cc-bytecomp-load (symbol-name ,cc-part)))
(require ,cc-part))))
@@ -301,12 +347,6 @@ afterwards. Don't use within `eval-when-compile'."
(require ,feature)
(eval-when-compile (cc-bytecomp-setup-environment))))
-(defun cc-bytecomp-is-compiling ()
- "Return non-nil if eval'ed during compilation. Don't use outside
-`eval-when-compile'."
- (and (boundp 'byte-compile-dest-file)
- (stringp byte-compile-dest-file)))
-
(defmacro cc-bytecomp-defvar (var)
"Binds the symbol as a variable during compilation of the file,
to silence the byte compiler. Don't use within `eval-when-compile'."
@@ -320,8 +360,7 @@ to silence the byte compiler. Don't use within `eval-when-compile'."
"cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
(setq cc-bytecomp-unbound-variables
(cons ',var cc-bytecomp-unbound-variables))))
- (if (and (cc-bytecomp-is-compiling)
- (not load-in-progress))
+ (if (cc-bytecomp-is-compiling)
(progn
(defvar ,var)
(set ',var (intern (concat "cc-bytecomp-ignore-var:"
@@ -349,8 +388,7 @@ at compile time, e.g. for macros and inline functions."
(setq cc-bytecomp-original-functions
(cons (list ',fun nil 'unbound)
cc-bytecomp-original-functions))))
- (if (and (cc-bytecomp-is-compiling)
- (not load-in-progress))
+ (if (cc-bytecomp-is-compiling)
(progn
(fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
(symbol-name ',fun))))