aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2015-01-13 15:39:36 +0000
committerAlan Mackenzie2015-01-13 15:47:26 +0000
commit30c5f5cdef8db72c007efecfc8436479631b45d0 (patch)
tree781d6e630b7efca6e0fef929a416bb79851949f5
parentc3024739131467b607fa745daf52ca25a3fd3c4d (diff)
downloademacs-30c5f5cdef8db72c007efecfc8436479631b45d0.tar.gz
emacs-30c5f5cdef8db72c007efecfc8436479631b45d0.zip
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.
-rw-r--r--lisp/ChangeLog26
-rw-r--r--lisp/progmodes/cc-bytecomp.el72
-rw-r--r--lisp/progmodes/cc-defs.el43
-rw-r--r--lisp/progmodes/cc-langs.el5
4 files changed, 108 insertions, 38 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 532a10a1b71..072af5b1b91 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,29 @@
12015-01-13 Alan Mackenzie <acm@muc.de>
2
3 Allow compilation during loading of Modes derived from a CC Mode mode.
4 Fixes debbugs#19206.
5
6 * progmodes/cc-bytecomp.el (cc-bytecomp-compiling-or-loading): new
7 function which walks the stack to discover whether we're compiling
8 or loading.
9 (cc-bytecomp-is-compiling): Reformulate, and move towards
10 beginning.
11 (cc-bytecomp-is-loading): New defsubst.
12 (cc-bytecomp-setup-environment, cc-bytecomp-restore-environment):
13 Use the above defsubsts.
14 (cc-require-when-compile, cc-bytecomp-defvar)
15 (cc-bytecomp-defun): Simplify conditionals.
16
17 * progmodes/cc-defs.el (cc-bytecomp-compiling-or-loading):
18 "Borrow" this function from cc-bytecomp.el.
19 (c-get-current-file): Reformulate using the above.
20 (c-lang-defconst): Prevent duplicate entries of file names in a
21 symbol's 'source property.
22 (c-lang-const): Use cc-bytecomp-is-compiling.
23
24 * progmodes/cc-langs.el (c-make-init-lang-vars-fun): Use
25 cc-bytecomp-is-compiling.
26
12015-01-13 Stefan Monnier <monnier@iro.umontreal.ca> 272015-01-13 Stefan Monnier <monnier@iro.umontreal.ca>
2 28
3 * emacs-lisp/eieio-core.el (eieio-defclass): Fix call to `defclass' 29 * emacs-lisp/eieio-core.el (eieio-defclass): Fix call to `defclass'
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 @@
89 ;;`(message ,@args) 89 ;;`(message ,@args)
90 ) 90 )
91 91
92(defun cc-bytecomp-compiling-or-loading ()
93 ;; Determine whether byte-compilation or loading is currently active,
94 ;; returning 'compiling, 'loading or nil.
95 ;; If both are active, the "innermost" activity counts. Note that
96 ;; compilation can trigger loading (various `require' type forms)
97 ;; and loading can trigger compilation (the package manager does
98 ;; this). We walk the lisp stack if necessary.
99 (cond
100 ((and load-in-progress
101 (boundp 'byte-compile-dest-file)
102 (stringp byte-compile-dest-file))
103 (let ((n 0) elt)
104 (while (and
105 (setq elt (backtrace-frame n))
106 (not (and (car elt)
107 (memq (cadr elt)
108 '(load require
109 byte-compile-file byte-recompile-directory
110 batch-byte-compile)))))
111 (setq n (1+ n)))
112 (cond
113 ((memq (cadr elt) '(load require))
114 'loading)
115 ((memq (cadr elt) '(byte-compile-file
116 byte-recompile-directory
117 batch-byte-compile))
118 'compiling)
119 (t ; Can't happen.
120 (message "cc-bytecomp-compiling-or-loading: System flags spuriously set")
121 nil))))
122 (load-in-progress
123 ;; Being loaded.
124 'loading)
125 ((and (boundp 'byte-compile-dest-file)
126 (stringp byte-compile-dest-file))
127 ;; Being compiled.
128 'compiling)
129 (t
130 ;; Being evaluated interactively.
131 nil)))
132
133(defsubst cc-bytecomp-is-compiling ()
134 "Return non-nil if eval'ed during compilation."
135 (eq (cc-bytecomp-compiling-or-loading) 'compiling))
136
137(defsubst cc-bytecomp-is-loading ()
138 "Return non-nil if eval'ed during loading.
139Nil will be returned if we're in a compilation triggered by the loading."
140 (eq (cc-bytecomp-compiling-or-loading) 'loading))
141
92(defun cc-bytecomp-setup-environment () 142(defun cc-bytecomp-setup-environment ()
93 ;; Eval'ed during compilation to setup variables, functions etc 143 ;; Eval'ed during compilation to setup variables, functions etc
94 ;; declared with `cc-bytecomp-defvar' et al. 144 ;; declared with `cc-bytecomp-defvar' et al.
95 (if (not load-in-progress) 145 (if (not (cc-bytecomp-is-loading))
96 ;; Look at `load-in-progress' to tell whether we're called
97 ;; directly in the file being compiled or just from some file
98 ;; being loaded during compilation.
99 (let (p) 146 (let (p)
100 (if cc-bytecomp-environment-set 147 (if cc-bytecomp-environment-set
101 (error "Byte compilation environment already set - \ 148 (error "Byte compilation environment already set - \
@@ -143,7 +190,7 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
143(defun cc-bytecomp-restore-environment () 190(defun cc-bytecomp-restore-environment ()
144 ;; Eval'ed during compilation to restore variables, functions etc 191 ;; Eval'ed during compilation to restore variables, functions etc
145 ;; declared with `cc-bytecomp-defvar' et al. 192 ;; declared with `cc-bytecomp-defvar' et al.
146 (if (not load-in-progress) 193 (if (not (cc-bytecomp-is-loading))
147 (let (p) 194 (let (p)
148 (setq p cc-bytecomp-unbound-variables) 195 (setq p cc-bytecomp-unbound-variables)
149 (while p 196 (while p
@@ -287,8 +334,7 @@ use within `eval-when-compile'."
287 `(eval-when-compile 334 `(eval-when-compile
288 (if (and (fboundp 'cc-bytecomp-is-compiling) 335 (if (and (fboundp 'cc-bytecomp-is-compiling)
289 (cc-bytecomp-is-compiling)) 336 (cc-bytecomp-is-compiling))
290 (if (or (not load-in-progress) 337 (if (not (featurep ,cc-part))
291 (not (featurep ,cc-part)))
292 (cc-bytecomp-load (symbol-name ,cc-part))) 338 (cc-bytecomp-load (symbol-name ,cc-part)))
293 (require ,cc-part)))) 339 (require ,cc-part))))
294 340
@@ -301,12 +347,6 @@ afterwards. Don't use within `eval-when-compile'."
301 (require ,feature) 347 (require ,feature)
302 (eval-when-compile (cc-bytecomp-setup-environment)))) 348 (eval-when-compile (cc-bytecomp-setup-environment))))
303 349
304(defun cc-bytecomp-is-compiling ()
305 "Return non-nil if eval'ed during compilation. Don't use outside
306`eval-when-compile'."
307 (and (boundp 'byte-compile-dest-file)
308 (stringp byte-compile-dest-file)))
309
310(defmacro cc-bytecomp-defvar (var) 350(defmacro cc-bytecomp-defvar (var)
311 "Binds the symbol as a variable during compilation of the file, 351 "Binds the symbol as a variable during compilation of the file,
312to silence the byte compiler. Don't use within `eval-when-compile'." 352to 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'."
320 "cc-bytecomp-defvar: Saving %s (as unbound)" ',var) 360 "cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
321 (setq cc-bytecomp-unbound-variables 361 (setq cc-bytecomp-unbound-variables
322 (cons ',var cc-bytecomp-unbound-variables)))) 362 (cons ',var cc-bytecomp-unbound-variables))))
323 (if (and (cc-bytecomp-is-compiling) 363 (if (cc-bytecomp-is-compiling)
324 (not load-in-progress))
325 (progn 364 (progn
326 (defvar ,var) 365 (defvar ,var)
327 (set ',var (intern (concat "cc-bytecomp-ignore-var:" 366 (set ',var (intern (concat "cc-bytecomp-ignore-var:"
@@ -349,8 +388,7 @@ at compile time, e.g. for macros and inline functions."
349 (setq cc-bytecomp-original-functions 388 (setq cc-bytecomp-original-functions
350 (cons (list ',fun nil 'unbound) 389 (cons (list ',fun nil 'unbound)
351 cc-bytecomp-original-functions)))) 390 cc-bytecomp-original-functions))))
352 (if (and (cc-bytecomp-is-compiling) 391 (if (cc-bytecomp-is-compiling)
353 (not load-in-progress))
354 (progn 392 (progn
355 (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:" 393 (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
356 (symbol-name ',fun)))) 394 (symbol-name ',fun))))
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 2ea566a7a25..d0beab1d485 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1983,19 +1983,22 @@ system."
1983 1983
1984(defvar c-lang-const-expansion nil) 1984(defvar c-lang-const-expansion nil)
1985 1985
1986;; Ugly hack to pull in the definition of `cc-bytecomp-compiling-or-loading`
1987;; from cc-bytecomp to make it available at loadtime. This is the same
1988;; mechanism used in cc-mode.el for `c-populate-syntax-table'.
1989(defalias 'cc-bytecomp-compiling-or-loading
1990 (cc-eval-when-compile
1991 (let ((f (symbol-function 'cc-bytecomp-compiling-or-loading)))
1992 (if (byte-code-function-p f) f (byte-compile f)))))
1993
1986(defsubst c-get-current-file () 1994(defsubst c-get-current-file ()
1987 ;; Return the base name of the current file. 1995 ;; Return the base name of the current file.
1988 (let ((file (cond 1996 (let* ((c-or-l (cc-bytecomp-compiling-or-loading))
1989 (load-in-progress 1997 (file
1990 ;; Being loaded. 1998 (cond
1991 load-file-name) 1999 ((eq c-or-l 'loading) load-file-name)
1992 ((and (boundp 'byte-compile-dest-file) 2000 ((eq c-or-l 'compiling) byte-compile-dest-file)
1993 (stringp byte-compile-dest-file)) 2001 ((null c-or-l) (buffer-file-name)))))
1994 ;; Being compiled.
1995 byte-compile-dest-file)
1996 (t
1997 ;; Being evaluated interactively.
1998 (buffer-file-name)))))
1999 (and file 2002 (and file
2000 (file-name-sans-extension 2003 (file-name-sans-extension
2001 (file-name-nondirectory file))))) 2004 (file-name-nondirectory file)))))
@@ -2062,6 +2065,9 @@ constant. A file is identified by its base name."
2062 ;; language constant source definitions.) 2065 ;; language constant source definitions.)
2063 (c-lang-const-expansion 'call) 2066 (c-lang-const-expansion 'call)
2064 (c-langs-are-parametric t) 2067 (c-langs-are-parametric t)
2068 (file (intern
2069 (or (c-get-current-file)
2070 (error "`c-lang-defconst' can only be used in a file"))))
2065 bindings 2071 bindings
2066 pre-files) 2072 pre-files)
2067 2073
@@ -2121,9 +2127,14 @@ constant. A file is identified by its base name."
2121 ;; definitions for this symbol, to make sure the order in the 2127 ;; definitions for this symbol, to make sure the order in the
2122 ;; `source' property is correct even when files are loaded out of 2128 ;; `source' property is correct even when files are loaded out of
2123 ;; order. 2129 ;; order.
2124 (setq pre-files (nreverse 2130 (setq pre-files (mapcar 'car (get sym 'source)))
2125 ;; Reverse to get the right load order. 2131 (if (memq file pre-files)
2126 (mapcar 'car (get sym 'source)))) 2132 ;; This can happen when the source file (e.g. cc-langs.el) is first
2133 ;; loaded as source, setting a 'source property entry, and then itself
2134 ;; being compiled.
2135 (setq pre-files (cdr (memq file pre-files))))
2136 ;; Reverse to get the right load order.
2137 (setq pre-files (nreverse pre-files))
2127 2138
2128 `(eval-and-compile 2139 `(eval-and-compile
2129 (c-define-lang-constant ',name ,bindings 2140 (c-define-lang-constant ',name ,bindings
@@ -2233,9 +2244,7 @@ quoted."
2233 (if (or (eq c-lang-const-expansion 'call) 2244 (if (or (eq c-lang-const-expansion 'call)
2234 (and (not c-lang-const-expansion) 2245 (and (not c-lang-const-expansion)
2235 (not mode)) 2246 (not mode))
2236 load-in-progress 2247 (not (cc-bytecomp-is-compiling)))
2237 (not (boundp 'byte-compile-dest-file))
2238 (not (stringp byte-compile-dest-file)))
2239 ;; Either a straight call is requested in the context, or 2248 ;; Either a straight call is requested in the context, or
2240 ;; we're in an "uncontrolled" context and got no language, 2249 ;; we're in an "uncontrolled" context and got no language,
2241 ;; or we're not being byte compiled so the compile time 2250 ;; or we're not being byte compiled so the compile time
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 17d717e740f..4d16a9b9d33 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -3260,10 +3260,7 @@ function it returns is byte compiled with all the evaluated results
3260from the language constants. Use the `c-init-language-vars' macro to 3260from the language constants. Use the `c-init-language-vars' macro to
3261accomplish that conveniently." 3261accomplish that conveniently."
3262 3262
3263 (if (and (not load-in-progress) 3263 (if (cc-bytecomp-is-compiling)
3264 (boundp 'byte-compile-dest-file)
3265 (stringp byte-compile-dest-file))
3266
3267 ;; No need to byte compile this lambda since the byte compiler is 3264 ;; No need to byte compile this lambda since the byte compiler is
3268 ;; smart enough to detect the `funcall' construct in the 3265 ;; smart enough to detect the `funcall' construct in the
3269 ;; `c-init-language-vars' macro below and compile it all straight 3266 ;; `c-init-language-vars' macro below and compile it all straight