emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Avoiding loading cc-langs


From: Stefan Monnier
Subject: Re: Avoiding loading cc-langs
Date: Mon, 08 Sep 2014 14:45:02 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4.50 (gnu/linux)

>>> run-time was placed in the separate file cc-langs.el, so as not to
>>> burden the run-time store occupancy needlessly.
>> Actually, a lot of what's in cc-langs.el *is* needed at run-time
> And as reported in http://debbugs.gnu.org/17463, in semi-recent Emacs,
> cc-langs gets loaded at runtime anyway. The whole thing is so complex
> that no-one shows any signs of figuring out why; can't say I blame them.
> I really hope this can be simplified.

This can be simplified, of course.  It does come with a performance
cost, tho.

My measurements with a work-in-progress patch indicate the following:

- the startup performance is the most affected: starting Emacs, opening
  an empty C++ file twice, and exiting takes about 22% additional time
  (we're talking 0.705s vs 0.577s on a nettop).
- the run-time performance (tested by font-locking the last 40KB of
  xdisp.c) is basically unchanged, tho repeated measurements to filter
  out the noise indicate a slowdown of about 1%.
- on the flip side, the heap size is smaller if we initialize "the normal
  way" rather than "the current way": M-x memory-usage indicates that
  "the normal way" uses about 10KB more cons cells, but makes up for it
  by using fewer strings and vectors.  This is probably due to the fact
  that "the current way" ends up preloading the computed settings for
  all supported major modes, hence extra strings and vectors.
- the .elc files get smaller by not incorporating the precomputed values
  (about 100KB saved in cc-fonts.elc, and even a bit more in cc-mode.elc).

For those interested, the corresponding patch is below (includes various
random cleanups not directly related).


        Stefan


=== modified file 'lisp/progmodes/cc-awk.el'
--- lisp/progmodes/cc-awk.el    2014-02-10 01:34:22 +0000
+++ lisp/progmodes/cc-awk.el    2014-09-08 16:44:34 +0000
@@ -40,28 +40,8 @@
 
 ;;; Code:
 
-(eval-when-compile
-  (let ((load-path
-        (if (and (boundp 'byte-compile-dest-file)
-                 (stringp byte-compile-dest-file))
-            (cons (file-name-directory byte-compile-dest-file) load-path)
-          load-path)))
-    (load "cc-bytecomp" nil t)))
-
-(cc-require 'cc-defs)
-
-;; Silence the byte compiler.
-(cc-bytecomp-defvar font-lock-mode)    ; Checked with boundp before use.
-(cc-bytecomp-defvar c-new-BEG)
-(cc-bytecomp-defvar c-new-END)
-
-;; Some functions in cc-engine that are used below.  There's a cyclic
-;; dependency so it can't be required here.  (Perhaps some functions
-;; could be moved to cc-engine to avoid it.)
-(cc-bytecomp-defun c-backward-token-1)
-(cc-bytecomp-defun c-beginning-of-statement-1)
-(cc-bytecomp-defun c-backward-sws)
-(cc-bytecomp-defun c-forward-sws)
+(require 'cc-defs)
+(require 'cc-engine)
 
 (defvar awk-mode-syntax-table
   (let ((st (make-syntax-table)))
@@ -782,30 +762,30 @@
             (t nil)))))                 ; Unterminated regexp at EOB
 
 (defun c-awk-set-syntax-table-properties (lim)
-;;     Scan the buffer text between point and LIM, setting (and clearing) the
-;; syntax-table property where necessary.
-;;
-;; This function is designed to be called as the FUNCTION in a MATCHER in
-;; font-lock-syntactic-keywords, and it always returns NIL (to inhibit
-;; repeated calls from font-lock: See elisp info page "Search-based
-;; Fontification").  It also gets called, with a bit of glue, from
-;; after-change-functions when font-lock isn't active.  Point is left
-;; "undefined" after this function exits.  THE BUFFER SHOULD HAVE BEEN
-;; WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED BEFORE CALLING THIS ROUTINE.
-;;
-;; We need to set/clear the syntax-table property on:
-;; (i) / - It is set to "string" on a / which is the opening or closing
-;;     delimiter of the properly terminated regexp (and left unset on a
-;;     division sign).
-;; (ii) the opener of an unterminated string/regexp, we set the property
-;;    "generic string delimiter" on both the opening " or / and the end of the
-;;    line where the closing delimiter is missing.
-;; (iii) "s inside strings/regexps (these will all be escaped "s).  They are
-;;   given the property "punctuation".  This will later allow other routines
-;;   to use the regexp "\\S\"*" to skip over the string innards.
-;; (iv) Inside a comment, all syntax-table properties are cleared.
-;;
-;; This function does hidden buffer changes.
+    "Scan the buffer text between point and LIM, setting (and clearing) the
+syntax-table property where necessary.
+
+This function is designed to be called as the FUNCTION in a MATCHER in
+font-lock-syntactic-keywords, and it always returns NIL (to inhibit
+repeated calls from font-lock: See elisp info page \"Search-based
+Fontification\").  It also gets called, with a bit of glue, from
+after-change-functions when font-lock isn't active.  Point is left
+\"undefined\" after this function exits.  THE BUFFER SHOULD HAVE BEEN
+WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED BEFORE CALLING THIS ROUTINE.
+
+We need to set/clear the syntax-table property on:
+\(i) / - It is set to \"string\" on a / which is the opening or closing
+    delimiter of the properly terminated regexp (and left unset on a
+    division sign).
+\(ii) the opener of an unterminated string/regexp, we set the property
+   \"generic string delimiter\" on both the opening \" or / and the end of the
+   line where the closing delimiter is missing.
+\(iii) \"s inside strings/regexps (these will all be escaped \"s).  They are
+  given the property \"punctuation\".  This will later allow other routines
+  to use the regexp \"\\\\S\\\"*\" to skip over the string innards.
+\(iv) Inside a comment, all syntax-table properties are cleared.
+
+This function does hidden buffer changes."
   (let (anchor
        (anchor-state-/div nil)) ; t means a following / would be a div sign.
     (c-awk-beginning-of-logical-line) ; ACM 2002/7/21.  This is probably 
redundant.
@@ -875,22 +855,25 @@
 ;; Don't overlook the possibility of the buffer change being the "recapturing"
 ;; of a previously escaped newline.
 
+(defvar c-new-BEG)
+(defvar c-new-END)
+
 ;; ACM 2008-02-05:
 (defun c-awk-extend-and-syntax-tablify-region (beg end old-len)
-  ;; Expand the region (BEG END) as needed to (c-new-BEG c-new-END) then put
-  ;; `syntax-table' properties on this region.
-  ;;
-  ;; This function is called from an after-change function, BEG END and
-  ;; OLD-LEN being the standard parameters.
-  ;;
-  ;; Point is undefined both before and after this function call, the buffer
-  ;; has been widened, and match-data saved.  The return value is ignored.
-  ;;
-  ;; It prepares the buffer for font
-  ;; locking, hence must get called before `font-lock-after-change-function'.
-  ;;
-  ;; This function is the AWK value of `c-before-font-lock-function'.
-  ;; It does hidden buffer changes.
+  "Expand the region (BEG END) as needed to (c-new-BEG c-new-END) then put
+`syntax-table' properties on this region.
+
+This function is called from an after-change function, BEG END and
+OLD-LEN being the standard parameters.
+
+Point is undefined both before and after this function call, the buffer
+has been widened, and match-data saved.  The return value is ignored.
+
+It prepares the buffer for font
+locking, hence must get called before `font-lock-after-change-function'.
+
+This function is the AWK value of `c-before-font-lock-function'.
+It does hidden buffer changes."
   (c-save-buffer-state ()
     (setq c-new-END (c-awk-end-of-change-region beg end old-len))
     (setq c-new-BEG (c-awk-beginning-of-logical-line beg))
@@ -1145,6 +1128,5 @@
          (goto-char (min start-point end-point)))))))
 
 
-(cc-provide 'cc-awk)                   ; Changed from 'awk-mode, ACM 2002/5/21
-
+(provide 'cc-awk)
 ;;; awk-mode.el ends here

=== modified file 'lisp/progmodes/cc-defs.el'
--- lisp/progmodes/cc-defs.el   2014-08-28 20:37:13 +0000
+++ lisp/progmodes/cc-defs.el   2014-09-08 16:03:02 +0000
@@ -195,7 +195,7 @@
 to it is returned.  This function does not modify the point or the mark."
 
   (if (eq (car-safe position) 'quote)
-      (let ((position (eval position)))
+      (let ((position (nth 1 position)))
        (cond
 
         ((eq position 'bol)
@@ -885,7 +885,7 @@
       `(c-lang-major-mode-is ,mode)
 
     (if (eq (car-safe mode) 'quote)
-       (let ((mode (eval mode)))
+       (let ((mode (nth 1 mode)))
          (if (listp mode)
              `(memq c-buffer-is-cc-mode ',mode)
            `(eq c-buffer-is-cc-mode ',mode)))
@@ -900,26 +900,10 @@
 ;; properties set on a single character and that never spread to any
 ;; other characters.
 
-(eval-and-compile
-  ;; Constant used at compile time to decide whether or not to use
-  ;; XEmacs extents.  Check all the extent functions we'll use since
-  ;; some packages might add compatibility aliases for some of them in
-  ;; Emacs.
-  (defconst c-use-extents (and (cc-bytecomp-fboundp 'extent-at)
-                              (cc-bytecomp-fboundp 'set-extent-property)
-                              (cc-bytecomp-fboundp 'set-extent-properties)
-                              (cc-bytecomp-fboundp 'make-extent)
-                              (cc-bytecomp-fboundp 'extent-property)
-                              (cc-bytecomp-fboundp 'delete-extent)
-                              (cc-bytecomp-fboundp 'map-extents))))
-
 ;; `c-put-char-property' is complex enough in XEmacs and Emacs < 21 to
 ;; make it a function.
 (defalias 'c-put-char-property-fun
-  (cc-eval-when-compile
-    (cond (c-use-extents
-          ;; XEmacs.
-          (byte-compile
+  (cond ((featurep 'xemacs)
            (lambda (pos property value)
              (let ((ext (extent-at pos nil property)))
                (if ext
@@ -928,20 +912,19 @@
                                         (cons property
                                               (cons value
                                                     '(start-open t
-                                                      end-open t)))))))))
+                                                    end-open t))))))))
 
          ((not (cc-bytecomp-boundp 'text-property-default-nonsticky))
           ;; In Emacs < 21 we have to mess with the `rear-nonsticky' property.
-          (byte-compile
            (lambda (pos property value)
              (put-text-property pos (1+ pos) property value)
              (let ((prop (get-text-property pos 'rear-nonsticky)))
                (or (memq property prop)
                    (put-text-property pos (1+ pos)
                                       'rear-nonsticky
-                                      (cons property prop)))))))
+                                    (cons property prop))))))
          ;; This won't be used for anything.
-         (t 'ignore))))
+        (t #'ignore)))
 (cc-bytecomp-defun c-put-char-property-fun) ; Make it known below.
 
 (defmacro c-put-char-property (pos property value)
@@ -956,42 +939,38 @@
   ;; 21) then it's assumed that the property is present on it.
   ;;
   ;; This macro does a hidden buffer change.
-  (setq property (eval property))
-  (if (or c-use-extents
+  (if (or (featurep 'xemacs)
          (not (cc-bytecomp-boundp 'text-property-default-nonsticky)))
       ;; XEmacs and Emacs < 21.
-      `(c-put-char-property-fun ,pos ',property ,value)
+      `(c-put-char-property-fun ,pos ,property ,value)
     ;; In Emacs 21 we got the `rear-nonsticky' property covered
     ;; by `text-property-default-nonsticky'.
     `(let ((-pos- ,pos))
-       (put-text-property -pos- (1+ -pos-) ',property ,value))))
+       (put-text-property -pos- (1+ -pos-) ,property ,value))))
 
 (defmacro c-get-char-property (pos property)
   ;; Get the value of the given property on the character at POS if
   ;; it's been put there by `c-put-char-property'.  PROPERTY is
   ;; assumed to be constant.
-  (setq property (eval property))
-  (if c-use-extents
+  (if (featurep 'xemacs)
       ;; XEmacs.
-      `(let ((ext (extent-at ,pos nil ',property)))
-        (if ext (extent-property ext ',property)))
+      `(let ((ext (extent-at ,pos nil ,property)))
+        (if ext (extent-property ext ,property)))
     ;; Emacs.
-    `(get-text-property ,pos ',property)))
+    `(get-text-property ,pos ,property)))
 
 ;; `c-clear-char-property' is complex enough in Emacs < 21 to make it
 ;; a function, since we have to mess with the `rear-nonsticky' property.
 (defalias 'c-clear-char-property-fun
-  (cc-eval-when-compile
-    (unless (or c-use-extents
+  (unless (or (featurep 'xemacs)
                (cc-bytecomp-boundp 'text-property-default-nonsticky))
-      (byte-compile
        (lambda (pos property)
         (when (get-text-property pos property)
           (remove-text-properties pos (1+ pos) (list property nil))
           (put-text-property pos (1+ pos)
                              'rear-nonsticky
                              (delq property (get-text-property
-                                             pos 'rear-nonsticky)))))))))
+                                           pos 'rear-nonsticky)))))))
 (cc-bytecomp-defun c-clear-char-property-fun) ; Make it known below.
 
 (defmacro c-clear-char-property (pos property)
@@ -1000,8 +979,10 @@
   ;; constant.
   ;;
   ;; This macro does a hidden buffer change.
-  (setq property (eval property))
-  (cond (c-use-extents
+  (if (eq 'quote (car-safe property))
+      (setq property (nth 1 property))
+    (error "`property' should be a quoted constant"))
+  (cond ((featurep 'xemacs)
         ;; XEmacs.
         `(let ((ext (extent-at ,pos nil ',property)))
            (if ext (delete-extent ext))))
@@ -1026,8 +1007,10 @@
   ;; `syntax-table'.
   ;;
   ;; This macro does hidden buffer changes.
-  (setq property (eval property))
-  (if c-use-extents
+  (if (eq 'quote (car-safe property))
+      (setq property (nth 1 property))
+    (error "`property' should be a quoted constant"))
+  (if (featurep 'xemacs)
       ;; XEmacs.
       `(map-extents (lambda (ext ignored)
                      (delete-extent ext))
@@ -1097,7 +1080,7 @@
 which have the value VALUE, as tested by `equal'.  These
 properties are assumed to be over individual characters, having
 been put there by c-put-char-property.  POINT remains unchanged."
-  (if c-use-extents
+  (if (featurep 'xemacs)
     ;; XEmacs
       `(let ((-property- ,property))
         (map-extents (lambda (ext val)
@@ -1816,8 +1799,6 @@
 and other miscellaneous data.  The obarray might also contain
 various other symbols, but those don't have any variable bindings.")
 
-(defvar c-lang-const-expansion nil)
-
 (defsubst c-get-current-file ()
   ;; Return the base name of the current file.
   (let ((file (cond
@@ -1881,25 +1862,7 @@
 constant.  A file is identified by its base name."
 
   (let* ((sym (intern (symbol-name name) c-lang-constants))
-        ;; Make `c-lang-const' expand to a straightforward call to
-        ;; `c-get-lang-constant' in `macroexpand-all' below.
-        ;;
-        ;; (The default behavior, i.e. to expand to a call inside
-        ;; `eval-when-compile' should be equivalent, since that macro
-        ;; should only expand to its content if it's used inside a
-        ;; form that's already evaluated at compile time.  It's
-        ;; however necessary to use our cover macro
-        ;; `cc-eval-when-compile' due to bugs in `eval-when-compile',
-        ;; and it expands to a bulkier form that in this case only is
-        ;; unnecessary garbage that we don't want to store in the
-        ;; language constant source definitions.)
-        (c-lang-const-expansion 'call)
-        (c-langs-are-parametric t)
-        bindings
-        pre-files)
-
-    (or (symbolp name)
-       (error "Not a symbol: %S" name))
+        bindings)
 
     (when (stringp (car-safe args))
       ;; The docstring is hardly used anywhere since there's no normal
@@ -1937,30 +1900,13 @@
        (setq args (cdr args)
              val (car args))
 
-       ;; Emacs has a weird bug where it seems to fail to read
-       ;; backquote lists from byte compiled files correctly (,@
-       ;; forms, to be specific), so make sure the bindings in the
-       ;; expansion below don't contain any backquote stuff.
-       ;; (XEmacs handles it correctly and doesn't need this for that
-       ;; reason, but we also use this expansion handle
-       ;; `c-lang-defconst-eval-immediately' and to register
-       ;; dependencies on the `c-lang-const's in VAL.)
-       (setq val (macroexpand-all val))
+        (let ((c-langs-are-parametric t))
+          (setq val (macroexpand-all val)))
 
        (setq bindings `(cons (cons ',assigned-mode (lambda () ,val)) ,bindings)
              args (cdr args))))
 
-    ;; Compile in the other files that have provided source
-    ;; definitions for this symbol, to make sure the order in the
-    ;; `source' property is correct even when files are loaded out of
-    ;; order.
-    (setq pre-files (nreverse
-                    ;; Reverse to get the right load order.
-                    (mapcar 'car (get sym 'source))))
-
-    `(eval-and-compile
-       (c-define-lang-constant ',name ,bindings
-                              ,@(and pre-files `(',pre-files))))))
+    `(c-define-lang-constant ',name ,bindings)))
 
 (put 'c-lang-defconst 'lisp-indent-function 1)
 ;(eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
@@ -1968,7 +1914,7 @@
 (def-edebug-spec c-lang-defconst
   (&define name [&optional stringp] [&rest sexp def-form]))
 
-(defun c-define-lang-constant (name bindings &optional pre-files)
+(defun c-define-lang-constant (name bindings)
   ;; Used by `c-lang-defconst'.
 
   (let* ((sym (intern (symbol-name name) c-lang-constants))
@@ -1985,10 +1931,6 @@
     ;; `c-lang-defconst' reverses the bindings, this reverses the
     ;; order between files so that the last to evaluate comes first.
     (unless elem
-      (while pre-files
-       (unless (assq (car pre-files) source)
-         (setq source (cons (list (car pre-files)) source)))
-       (setq pre-files (cdr pre-files)))
       (put sym 'source (cons (setq elem (list file)) source)))
 
     (setcdr elem bindings)
@@ -2023,11 +1965,6 @@
 language.  NAME and LANG are not evaluated so they should not be
 quoted."
 
-  (or (symbolp name)
-      (error "Not a symbol: %S" name))
-  (or (symbolp lang)
-      (error "Not a symbol: %S" lang))
-
   (let ((sym (intern (symbol-name name) c-lang-constants))
        (mode (when lang (intern (concat (symbol-name lang) "-mode")))))
 
@@ -2035,53 +1972,11 @@
         (error "Unknown language %S: no `c-mode-prefix' property"
                lang))
 
-    (if (eq c-lang-const-expansion 'immediate)
-       ;; No need to find out the source file(s) when we evaluate
-       ;; immediately since all the info is already there in the
-       ;; `source' property.
-       `',(c-get-lang-constant name nil mode)
-
-      (let ((source-files
-             (let ((file (c-get-current-file)))
-               (if file (setq file (intern file)))
-               ;; Get the source file(s) that must be loaded to get the value
-               ;; of the constant.  If the symbol isn't defined yet we assume
-               ;; that its definition will come later in this file, and thus
-               ;; are no file dependencies needed.
-               (nreverse
-                ;; Reverse to get the right load order.
-                (apply 'nconc
-                       (mapcar (lambda (elem)
-                                 (if (eq file (car elem))
-                                     nil ; Exclude our own file.
-                                   (list (car elem))))
-                               (get sym 'source))))))
-            ;; Make some effort to do a compact call to
+    (let (;; Make some effort to do a compact call to
             ;; `c-get-lang-constant' since it will be compiled in.
-            (args (and mode `(',mode))))
-
-        (if (or source-files args)
-            (push (and source-files `',source-files) args))
+          (args (and mode `(nil ',mode))))
 
-        (if (or (eq c-lang-const-expansion 'call)
-                (and (not c-lang-const-expansion)
-                     (not mode))
-                load-in-progress
-                (not (boundp 'byte-compile-dest-file))
-                (not (stringp byte-compile-dest-file)))
-            ;; Either a straight call is requested in the context, or
-            ;; we're in an "uncontrolled" context and got no language,
-            ;; or we're not being byte compiled so the compile time
-            ;; stuff below is unnecessary.
-            `(c-get-lang-constant ',name ,@args)
-
-          ;; Being compiled.  If the loading and compiling version is
-          ;; the same we use a value that is evaluated at compile time,
-          ;; otherwise it's evaluated at runtime.
-          `(if (eq c-version-sym ',c-version-sym)
-               (cc-eval-when-compile
-                 (c-get-lang-constant ',name ,@args))
-             (c-get-lang-constant ',name ,@args)))))))
+      `(c-get-lang-constant ',name ,@args))))
 
 (defvar c-lang-constants-under-evaluation nil
   "Alist of constants in the process of being evaluated.
@@ -2092,7 +1987,7 @@
 
 (defconst c-lang--novalue "novalue")
 
-(defun c-get-lang-constant (name &optional source-files mode)
+(defun c-get-lang-constant (name &optional _source-files mode)
   ;; Used by `c-lang-const'.
 
   (or mode
@@ -2111,19 +2006,6 @@
       (or (memq eval-in-sym (get sym 'dependents))
          (put sym 'dependents (cons eval-in-sym (get sym 'dependents)))))
 
-    ;; Make sure the source files have entries on the `source'
-    ;; property so that loading will take place when necessary.
-    (while source-files
-      (unless (assq (car source-files) source)
-       (put sym 'source
-            (setq source (cons (list (car source-files)) source)))
-       ;; Might pull in more definitions which affect the value.  The
-       ;; clearing of dependent values etc is done when the
-       ;; definition is encountered during the load; this is just to
-       ;; jump past the check for a cached value below.
-       (set sym nil))
-      (setq source-files (cdr source-files)))
-
     (if (and (boundp sym)
             (setq elem (assq mode (symbol-value sym))))
        (cdr elem)
@@ -2208,34 +2090,15 @@
          (assignment-entry (elt source-pos 1))
          assignment)
 
-      (while (if assignment-entry
-                t
+      (while (or assignment-entry
               ;; Handled the last assignment from one file, begin on the
               ;; next.  Due to the check in `c-lang-defconst', we know
               ;; there's at least one.
               (when file-entry
-
                 (unless (aset source-pos 1
                               (setq assignment-entry (cdar file-entry)))
-                  ;; The file containing the source definitions has not
-                  ;; been loaded.
-                  (let ((file (symbol-name (caar file-entry)))
-                        (c-lang-constants-under-evaluation nil))
-                    ;;(message (concat "Loading %s to get the source "
-                    ;;                 "value for language constant %s")
-                    ;;         file name)
-                    (load file nil t))
-
-                  (unless (setq assignment-entry (cdar file-entry))
-                    ;; The load didn't fill in the source for the
-                    ;; constant as expected.  The situation is
-                    ;; probably that a derived mode was written for
-                    ;; and compiled with another version of CC Mode,
-                    ;; and the requested constant isn't in the
-                    ;; currently loaded one.  Put in a dummy
-                    ;; assignment that matches no language.
-                    (setcdr (car file-entry)
-                            (setq assignment-entry (list (list nil))))))
+                     (error "Missing c-lang-const data from file %S"
+                            (caar file-entry)))
 
                 (aset source-pos 0 (setq file-entry (cdr file-entry)))
                 t))

=== modified file 'lisp/progmodes/cc-engine.el'
--- lisp/progmodes/cc-engine.el 2014-08-24 20:50:11 +0000
+++ lisp/progmodes/cc-engine.el 2014-09-08 15:42:16 +0000
@@ -144,24 +144,10 @@
     (load "cc-bytecomp" nil t)))
 
 (cc-require 'cc-defs)
-(cc-require-when-compile 'cc-langs)
+(cc-require 'cc-langs)
 (cc-require 'cc-vars)
 
 
-;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
-
-(defmacro c-declare-lang-variables ()
-  `(progn
-     ,@(apply 'nconc
-             (mapcar (lambda (init)
-                       `(,(if (elt init 2)
-                              `(defvar ,(car init) nil ,(elt init 2))
-                            `(defvar ,(car init) nil))
-                         (make-variable-buffer-local ',(car init))))
-                     (cdr c-lang-variable-inits)))))
-(c-declare-lang-variables)
-
-
 ;;; Internal state variables.
 
 ;; Internal state of hungry delete key feature
@@ -4119,10 +4105,10 @@
                                 (c-end-of-current-token last-token-end-pos))
                               (setq last-token-end-pos (point))))))
                 ;; Inside a token.
-                (if lookbehind-submatch
+                (goto-char (if lookbehind-submatch
                     ;; See the NOTE above.
-                    (goto-char state-pos)
-                  (goto-char (min last-token-end-pos bound))))
+                               state-pos
+                             (min last-token-end-pos bound))))
 
                (t
                 ;; A real match.

=== modified file 'lisp/progmodes/cc-fonts.el'
--- lisp/progmodes/cc-fonts.el  2014-08-24 20:50:11 +0000
+++ lisp/progmodes/cc-fonts.el  2014-09-08 15:42:16 +0000
@@ -64,6 +64,8 @@
 ;; o  `font-lock-keyword-face' and the face in `c-label-face-name' are
 ;;    never overlaid with other faces.
 
+(eval-when-compile (require 'cl))
+
 (eval-when-compile
   (let ((load-path
         (if (and (boundp 'byte-compile-dest-file)
@@ -73,7 +75,7 @@
     (load "cc-bytecomp" nil t)))
 
 (cc-require 'cc-defs)
-(cc-require-when-compile 'cc-langs)
+(cc-require 'cc-langs)
 (cc-require 'cc-vars)
 (cc-require 'cc-engine)
 (cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to
@@ -201,18 +203,13 @@
   :version "24.1"
   :group 'c)
 
-(eval-and-compile
-  ;; We need the following definitions during compilation since they're
-  ;; used when the `c-lang-defconst' initializers are evaluated.  Define
-  ;; them at runtime too for the sake of derived modes.
-
-  ;; This indicates the "font locking context", and is set just before
-  ;; fontification is done.  If non-nil, it says, e.g., point starts
-  ;; from within a #if preprocessor construct.
-  (defvar c-font-lock-context nil)
-  (make-variable-buffer-local 'c-font-lock-context)
+;; This indicates the "font locking context", and is set just before
+;; fontification is done.  If non-nil, it says, e.g., point starts
+;; from within a #if preprocessor construct.
+(defvar c-font-lock-context nil)
+(make-variable-buffer-local 'c-font-lock-context)
 
-  (defmacro c-put-font-lock-face (from to face)
+(defmacro c-put-font-lock-face (from to face)
     ;; Put a face on a region (overriding any existing face) in the way
     ;; font-lock would do it.  In XEmacs that means putting an
     ;; additional font-lock property, or else the font-lock package
@@ -226,7 +223,7 @@
        `(font-lock-set-face ,from ,to ,face)
       `(put-text-property ,from ,to 'face ,face)))
 
-  (defmacro c-remove-font-lock-face (from to)
+(defmacro c-remove-font-lock-face (from to)
     ;; This is the inverse of `c-put-font-lock-face'.
     ;;
     ;; This function does a hidden buffer change.
@@ -234,7 +231,7 @@
        `(font-lock-remove-face ,from ,to)
       `(remove-text-properties ,from ,to '(face nil))))
 
-  (defmacro c-put-font-lock-string-face (from to)
+(defmacro c-put-font-lock-string-face (from to)
     ;; Put `font-lock-string-face' on a string.  The surrounding
     ;; quotes are included in Emacs but not in XEmacs.  The passed
     ;; region should include them.
@@ -244,7 +241,7 @@
        `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
       `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
 
-  (defmacro c-fontify-types-and-refs (varlist &rest body)
+(defmacro c-fontify-types-and-refs (varlist &rest body)
     ;; Like `let', but additionally activates `c-record-type-identifiers'
     ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
     ;; accordingly on exit.
@@ -255,9 +252,9 @@
           ,@varlist)
        (prog1 (progn ,@body)
         (c-fontify-recorded-types-and-refs))))
-  (put 'c-fontify-types-and-refs 'lisp-indent-function 1)
+(put 'c-fontify-types-and-refs 'lisp-indent-function 1)
 
-  (defun c-skip-comments-and-strings (limit)
+(defun c-skip-comments-and-strings (limit)
     ;; If the point is within a region fontified as a comment or
     ;; string literal skip to the end of it or to LIMIT, whichever
     ;; comes first, and return t.  Otherwise return nil.  The match
@@ -272,7 +269,19 @@
                    (c-got-face-at (point) c-literal-faces))))
       t))
 
-  (defun c-make-syntactic-matcher (regexp)
+(defvar c-font-byte-compile nil
+  "If non-nil, byte-compile the dynamically-generated functions.
+It defaults to nil, since in practice, byte-compiling them gives no
+speed advantage anyway.")
+
+(defun c--compile (exp)
+  (cond
+   ((byte-code-function-p exp) (error "Already byte-compiled: %S" exp))
+   ((not (eq (car-safe exp) 'lambda)) (error "Expected a (lambda ..): %S" exp))
+   (c-font-byte-compile (byte-compile exp))
+   (t (eval (macroexpand-all exp)))))
+
+(defun c-make-syntactic-matcher (regexp)
     ;; Returns a byte compiled function suitable for use in place of a
     ;; regexp string in a `font-lock-keywords' matcher, except that
     ;; only matches outside comments and string literals count.
@@ -280,10 +289,10 @@
     ;; This function does not do any hidden buffer changes, but the
     ;; generated functions will.  (They are however used in places
     ;; covered by the font-lock context.)
-    (byte-compile
-     `(lambda (limit)
+  (lexical-let ((regexp regexp))
+    (lambda (limit)
        (let (res)
-         (while (and (setq res (re-search-forward ,regexp limit t))
+        (while (and (setq res (re-search-forward regexp limit t))
                      (progn
                        (goto-char (match-beginning 0))
                        (or (c-skip-comments-and-strings limit)
@@ -292,7 +301,7 @@
                              nil)))))
          res))))
 
-  (defun c-make-font-lock-search-form (regexp highlights)
+(defun c-make-font-lock-search-form (regexp highlights)
     ;; Return a lisp form which will fontify every occurrence of REGEXP
     ;; (a regular expression, NOT a function) between POINT and `limit'
     ;; with HIGHLIGHTS, a list of highlighters as specified on page
@@ -331,7 +340,7 @@
                   ,(nth 2 highlight))))
            highlights))))
 
-  (defun c-make-font-lock-search-function (regexp &rest highlights)
+(defun c-make-font-lock-search-function (regexp &rest highlights)
     ;; This function makes a byte compiled function that works much like
     ;; a matcher element in `font-lock-keywords'.  It cuts out a little
     ;; bit of the overhead compared to a real matcher.  The main reason
@@ -359,7 +368,7 @@
 
     ;; Note: Replace `byte-compile' with `eval' to debug the generated
     ;; lambda more easily.
-    (byte-compile
+  (c--compile
      `(lambda (limit)
        (let ( ;; The font-lock package in Emacs is known to clobber
              ;; `parse-sexp-lookup-properties' (when it exists).
@@ -401,7 +410,7 @@
 
        nil)))
 
-  (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights)
+(defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights)
     ;; This function makes a byte compiled function that first moves back
     ;; to the beginning of the current declaration (if any), then searches
     ;; forward for matcher elements (as in `font-lock-keywords') and
@@ -439,7 +448,7 @@
 
     ;; Note: Replace `byte-compile' with `eval' to debug the generated
     ;; lambda more easily.
-    (byte-compile
+  (c--compile
      `(lambda (limit)
        (let ( ;; The font-lock package in Emacs is known to clobber
              ;; `parse-sexp-lookup-properties' (when it exists).
@@ -456,7 +465,7 @@
          ,(c-make-font-lock-search-form regexp highlights))
        nil)))
 
-  (defun c-make-font-lock-context-search-function (normal &rest state-stanzas)
+(defun c-make-font-lock-context-search-function (normal &rest state-stanzas)
     ;; This function makes a byte compiled function that works much like
     ;; a matcher element in `font-lock-keywords', with the following
     ;; enhancement: the generated function will test for particular "font
@@ -490,7 +499,7 @@
     ;;
     ;; Note: Replace `byte-compile' with `eval' to debug the generated
     ;; lambda more easily.
-    (byte-compile
+  (c--compile
      `(lambda (limit)
        (let ( ;; The font-lock package in Emacs is known to clobber
              ;; `parse-sexp-lookup-properties' (when it exists).
@@ -511,15 +520,15 @@
          ,(c-make-font-lock-search-form (car normal) (cdr normal))
          nil))))
 
-;  (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
-;    '(progn
-  (def-edebug-spec c-fontify-types-and-refs let*)
-  (def-edebug-spec c-make-syntactic-matcher t)
-  ;; If there are literal quoted or backquoted highlight specs in
-  ;; the call to `c-make-font-lock-search-function' then let's
-  ;; instrument the forms in them.
-  (def-edebug-spec c-make-font-lock-search-function
-    (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)));))
+;; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
+;;    '(progn
+(def-edebug-spec c-fontify-types-and-refs let*)
+(def-edebug-spec c-make-syntactic-matcher t)
+;; If there are literal quoted or backquoted highlight specs in
+;; the call to `c-make-font-lock-search-function' then let's
+;; instrument the forms in them.
+(def-edebug-spec c-make-font-lock-search-function
+  (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form));))
 
 (defun c-fontify-recorded-types-and-refs ()
   ;; Convert the ranges recorded on `c-record-type-identifiers' and
@@ -581,7 +590,7 @@
 
                       ;; Use an anchored matcher to put paren syntax
                       ;; on the brackets.
-                      (,(byte-compile
+                      (,(c--compile
                          `(lambda (limit)
                             (let ((beg (match-beginning
                                         ,(+ ncle-depth re-depth sws-depth 1)))
@@ -683,7 +692,7 @@
                         "\\)")
                 `(,(1+ ncle-depth) c-preprocessor-face-name t)))
 
-             (eval . (list ,(c-make-syntactic-matcher
+             (eval . (list ',(c-make-syntactic-matcher
                              (concat noncontinued-line-end
                                      (c-lang-const c-opt-cpp-prefix)
                                      "if\\(n\\)def\\>"))
@@ -745,11 +754,11 @@
       ;; this, but it doesn't give the control we want since any
       ;; fontification done inside the function will be
       ;; unconditionally overridden.
-      ,(c-make-font-lock-search-function
+      (,(c-make-font-lock-search-function
        ;; Match a char before the string starter to make
        ;; `c-skip-comments-and-strings' work correctly.
        (concat ".\\(" c-string-limit-regexp "\\)")
-       '((c-font-lock-invalid-string)))
+         '((c-font-lock-invalid-string))))
 
       ;; Fontify keyword constants.
       ,@(when (c-lang-const c-constant-kwds)
@@ -801,7 +810,8 @@
                                    (c-backward-syntactic-ws)
                                    (setq id-end (point))
                                    (< (skip-chars-backward
-                                       ,(c-lang-const c-symbol-chars)) 0))
+                                       ,(c-lang-const c-symbol-chars))
+                                       0))
                                  (not (get-text-property (point) 'face)))
                        (c-put-font-lock-face (point) id-end
                                              c-reference-face-name)
@@ -809,7 +819,7 @@
                    nil
                    (goto-char (match-end 0)))))
 
-           `((,(byte-compile
+           `((,(c--compile
                 ;; Must use a function here since we match longer than
                 ;; we want to move before doing a new search.  This is
                 ;; not necessary for XEmacs since it restarts the
@@ -1564,9 +1574,7 @@
   ;; Note that this function won't attempt to fontify beyond the end of the
   ;; current enum block, if any.
   (let* ((paren-state (c-parse-state))
-        (encl-pos (c-most-enclosing-brace paren-state))
-        (start (point))
-       )
+        (encl-pos (c-most-enclosing-brace paren-state)))
     (when (and
           encl-pos
           (eq (char-after encl-pos) ?\{)
@@ -1617,8 +1625,7 @@
   t `(;; Objective-C methods.
       ,@(when (c-major-mode-is 'objc-mode)
          `((,(c-lang-const c-opt-method-key)
-            (,(byte-compile
-               (lambda (limit)
+            (,(lambda (limit)
                  (let (;; The font-lock package in Emacs is known to clobber
                        ;; `parse-sexp-lookup-properties' (when it exists).
                        (parse-sexp-lookup-properties
@@ -1627,7 +1634,7 @@
                    (save-restriction
                      (narrow-to-region (point-min) limit)
                      (c-font-lock-objc-method)))
-                 nil))
+                 nil)
              (goto-char (match-end 1))))))
 
       ;; Fontify all type names and the identifiers in the
@@ -1742,7 +1749,7 @@
 
       ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct").
       ,@(when (c-lang-const c-type-prefix-kwds)
-         `((,(byte-compile
+         `((,(c--compile
               `(lambda (limit)
                  (c-fontify-types-and-refs
                      ((c-promote-possible-types t)
@@ -2295,7 +2302,7 @@
      limit
      "[-+]"
      nil
-     (lambda (match-pos inside-macro)
+     (lambda (_match-pos _inside-macro)
        (forward-char)
        (c-font-lock-objc-method))))
   nil)

=== modified file 'lisp/progmodes/cc-langs.el'
--- lisp/progmodes/cc-langs.el  2014-08-24 20:50:11 +0000
+++ lisp/progmodes/cc-langs.el  2014-09-08 15:53:43 +0000
@@ -137,24 +137,13 @@
 
 ;;; Setup for the `c-lang-defvar' system.
 
-(eval-and-compile
-  ;; These are used to collect the init forms from the subsequent
-  ;; `c-lang-defvar' and `c-lang-setvar'.  They are used to build the
-  ;;  lambda in `c-make-init-lang-vars-fun' below, and to build `defvar's
-  ;;  and `make-variable-buffer-local's in cc-engine and
-  ;;  `make-local-variable's in `c-init-language-vars-for'.
-  (defvar c-lang-variable-inits nil)
-  (defvar c-lang-variable-inits-tail nil)
-  (setq c-lang-variable-inits (list nil)
-       c-lang-variable-inits-tail c-lang-variable-inits)
-  (defvar c-emacs-variable-inits nil)
-  (defvar c-emacs-variable-inits-tail nil)
-  (setq c-emacs-variable-inits (list nil)
-       c-emacs-variable-inits-tail c-emacs-variable-inits))
+(defvar c-lang--vars nil
+  "List of vars that need to be initialized buffer-locally.")
+
 
 (defmacro c-lang-defvar (var val &optional doc)
-  "Declares the buffer local variable VAR to get the value VAL.  VAL is
-evaluated and assigned at mode initialization.  More precisely, VAL is
+  "Declare the buffer local variable VAR to get the value VAL.
+VAL is evaluated and assigned at mode initialization.  More precisely, VAL is
 evaluated and bound to VAR when the result from the macro
 `c-init-language-vars' is evaluated.
 
@@ -162,10 +151,10 @@
 language being initialized, and such calls will be macro expanded to
 the evaluated constant value at compile time."
 
-  (when (and (not doc)
-            (eq (car-safe val) 'c-lang-const)
+  (let ((use-const (and (eq (car-safe val) 'c-lang-const)
             (eq (nth 1 val) var)
-            (not (nth 2 val)))
+                        (not (nth 2 val)))))
+    (when (and (not doc) use-const)
     ;; Special case: If there's no docstring and the value is a
     ;; simple (c-lang-const foo) where foo is the same name as VAR
     ;; then take the docstring from the language constant foo.
@@ -174,33 +163,14 @@
   (or (stringp doc)
       (setq doc nil))
 
-  (let ((elem (assq var (cdr c-lang-variable-inits))))
-    (if elem
-       (setcdr elem (list val doc))
-      (setcdr c-lang-variable-inits-tail (list (list var val doc)))
-      (setq c-lang-variable-inits-tail (cdr c-lang-variable-inits-tail))))
-
-  ;; Return the symbol, like the other def* forms.
-  `',var)
-
-(defmacro c-lang-setvar (var val)
-  "Causes the variable VAR to be made buffer local and to get set to the
-value VAL.  VAL is evaluated and assigned at mode initialization.  More
-precisely, VAL is evaluated and bound to VAR when the result from the
-macro `c-init-language-vars' is evaluated.  VAR is typically a standard
-Emacs variable like `comment-start'.
-
-`c-lang-const' is typically used in VAL to get the right value for the
-language being initialized, and such calls will be macro expanded to
-the evaluated constant value at compile time."
-  (let ((elem (assq var (cdr c-emacs-variable-inits))))
-    (if elem
-       (setcdr elem (list val)) ; Maybe remove "list", sometime. 2006-07-19
-      (setcdr c-emacs-variable-inits-tail (list (list var val)))
-      (setq c-emacs-variable-inits-tail (cdr c-emacs-variable-inits-tail))))
-
+    `(progn
+       (defvar ,var nil ,doc)
+       (make-variable-buffer-local ',var)
+       ,@(unless use-const
+           `((put ',var 'c-initialize-function (lambda () ,val))))
+       (add-to-list 'c-lang--vars ',var)
   ;; Return the symbol, like the other def* forms.
-  `',var)
+       ',var)))
 
 (put 'c-lang-defvar 'lisp-indent-function 'defun)
 ; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
@@ -214,44 +184,42 @@
 ;(declare-function delete-duplicates "cl-seq" (cl-seq &rest cl-keys) t)
 ;(declare-function mapcan "cl-extra" (cl-func cl-seq &rest cl-rest) t)
 
-(eval-and-compile
-  ;; Some helper functions used when building the language constants.
+;; Some helper functions used when building the language constants.
 
-  (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
-    ;; Extract a subset of the operators in the list OPS in a DWIM:ey
-    ;; way.  The return value is a plain list of operators:
-    ;;
-    ;; OPS either has the structure of `c-operators', is a single
-    ;; group in `c-operators', or is a plain list of operators.
-    ;;
-    ;; OPGROUP-FILTER specifies how to select the operator groups.  It
-    ;; can be t to choose all groups, a list of group type symbols
-    ;; (such as 'prefix) to accept, or a function which will be called
-    ;; with the group symbol for each group and should return non-nil
-    ;; if that group is to be included.
-    ;;
-    ;; If XLATE is given, it's a function which is called for each
-    ;; matching operator and its return value is collected instead.
-    ;; If it returns a list, the elements are spliced directly into
-    ;; the final result, which is returned as a list with duplicates
-    ;; removed using `equal'.
-    ;;
-    ;; `c-mode-syntax-table' for the current mode is in effect during
-    ;; the whole procedure.
+(defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
+  "Extract a subset of the operators in the list OPS in a DWIM:ey way.
+The return value is a plain list of operators:
+
+OPS either has the structure of `c-operators', is a single
+group in `c-operators', or is a plain list of operators.
+
+OPGROUP-FILTER specifies how to select the operator groups.  It
+can be t to choose all groups, a list of group type symbols
+\(such as 'prefix) to accept, or a function which will be called
+with the group symbol for each group and should return non-nil
+if that group is to be included.
+
+If XLATE is given, it's a function which is called for each
+matching operator and its return value is collected instead.
+If it returns a list, the elements are spliced directly into
+the final result, which is returned as a list with duplicates
+removed using `equal'.
+
+`c-mode-syntax-table' for the current mode is in effect during
+the whole procedure."
     (unless (listp (car-safe ops))
       (setq ops (list ops)))
-    (cond ((eq opgroup-filter t)
-          (setq opgroup-filter (lambda (opgroup) t)))
+  (let ((opgroup-filter
+         (cond ((eq opgroup-filter t) (lambda (opgroup) t))
          ((not (functionp opgroup-filter))
-          (setq opgroup-filter `(lambda (opgroup)
-                                  (memq opgroup ',opgroup-filter)))))
-    (cond ((eq op-filter t)
-          (setq op-filter (lambda (op) t)))
-         ((stringp op-filter)
-          (setq op-filter `(lambda (op)
-                             (string-match ,op-filter op)))))
+                `(lambda (opgroup) (memq opgroup ',opgroup-filter)))
+               (t opgroup-filter)))
+        (op-filter
+         (cond ((eq op-filter t) (lambda (op) t))
+               ((stringp op-filter) `(lambda (op) (string-match ,op-filter 
op)))
+               (t op-filter))))
     (unless xlate
-      (setq xlate 'identity))
+      (setq xlate #'identity))
     (c-with-syntax-table (c-lang-const c-mode-syntax-table)
       (cl-delete-duplicates
        (cl-mapcan (lambda (opgroup)
@@ -266,7 +234,7 @@
                                 (if (listp res) res (list res)))))
                           opgroup)))
               ops)
-       :test 'equal))))
+       :test #'equal))))
 
 
 ;;; Various mode specific values that aren't language related.
@@ -368,18 +336,18 @@
 (c-lang-defconst c-make-mode-syntax-table
   "Functions that generates the mode specific syntax tables.
 The syntax tables aren't stored directly since they're quite large."
-  t `(lambda ()
+  t (lambda ()
        (let ((table (make-syntax-table)))
         (c-populate-syntax-table table)
         ;; Mode specific syntaxes.
-        ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode))
+        (cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode))
                 ;; Let '@' be part of symbols in ObjC to cope with
                 ;; its compiler directives as single keyword tokens.
                 ;; This is then necessary since it's assumed that
                 ;; every keyword is a single symbol.
-                `(modify-syntax-entry ?@ "_" table))
+                (modify-syntax-entry ?@ "_" table))
                ((c-major-mode-is 'pike-mode)
-                `(modify-syntax-entry ?@ "." table)))
+                (modify-syntax-entry ?@ "." table)))
         table)))
 
 (c-lang-defconst c-mode-syntax-table
@@ -387,7 +355,7 @@
   ;; the constants in this file are evaluated.
   t (funcall (c-lang-const c-make-mode-syntax-table)))
 
-(c-lang-defconst c++-make-template-syntax-table
+(c-lang-defconst c++-template-syntax-table
   ;; A variant of `c++-mode-syntax-table' that defines `<' and `>' as
   ;; parenthesis characters.  Used temporarily when template argument
   ;; lists are parsed.  Note that this encourages incorrect parsing of
@@ -397,14 +365,13 @@
   ;; THIS SYNTAX TABLE IS CURRENT, `c-parse-state' MUST _NOT_ BE
   ;; CALLED!!!
   t   nil
-  (java c++) `(lambda ()
-        (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
+  (java c++)
+  (let ((table (funcall (c-lang-const c-make-mode-syntax-table))))
           (modify-syntax-entry ?< "(>" table)
           (modify-syntax-entry ?> ")<" table)
-          table)))
+    table))
 (c-lang-defvar c++-template-syntax-table
-  (and (c-lang-const c++-make-template-syntax-table)
-       (funcall (c-lang-const c++-make-template-syntax-table))))
+  (c-lang-const c++-template-syntax-table))
 
 (c-lang-defconst c-no-parens-syntax-table
   ;; A variant of the standard syntax table which is used to find matching
@@ -414,18 +381,17 @@
   ;; even when there's unbalanced other parens inside them.
   ;;
   ;; This variable is nil for languages which don't have template stuff.
-  t  `(lambda ()
-       (if (c-lang-const c-recognize-<>-arglists)
-           (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
+  t  (if (c-lang-const c-recognize-<>-arglists)
+         (let ((table (funcall (c-lang-const c-make-mode-syntax-table))))
              (modify-syntax-entry ?\( "." table)
              (modify-syntax-entry ?\) "." table)
              (modify-syntax-entry ?\[ "." table)
              (modify-syntax-entry ?\] "." table)
              (modify-syntax-entry ?\{ "." table)
              (modify-syntax-entry ?\} "." table)
-             table))))
+           table)))
 (c-lang-defvar c-no-parens-syntax-table
-              (funcall (c-lang-const c-no-parens-syntax-table)))
+              (c-lang-const c-no-parens-syntax-table))
 
 (c-lang-defconst c-identifier-syntax-modifications
   "A list that describes the modifications that should be done to the
@@ -1192,7 +1158,7 @@
         "=\\([^=]\\|$\\)"
         "\\|"
         (c-make-keywords-re nil
-          (set-difference (c-lang-const c-assignment-operators)
+          (cl-set-difference (c-lang-const c-assignment-operators)
                           '("=")
                           :test 'string-equal)))
       "\\<\\>"))
@@ -1244,7 +1210,7 @@
   ;; multicharacter tokens that begin with ">" except for those beginning with
   ;; ">>".
   t (c-make-keywords-re nil
-      (set-difference
+      (cl-set-difference
        (c-lang-const c->-op-cont-tokens)
        (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
                     t
@@ -1387,7 +1353,6 @@
   ;; In C we still default to the block comment style since line
   ;; comments aren't entirely portable.
   c "/* ")
-(c-lang-setvar comment-start (c-lang-const comment-start))
 
 (c-lang-defconst comment-end
   "String that ends comments inserted with M-; etc.
@@ -1400,7 +1365,6 @@
                      (c-lang-const comment-start))
        (concat " " (c-lang-const c-block-comment-ender))
       ""))
-(c-lang-setvar comment-end (c-lang-const comment-end))
 
 (c-lang-defconst comment-start-skip
   "Regexp to match the start of a comment plus everything up to its body.
@@ -1416,7 +1380,6 @@
                           (c-lang-const c-block-comment-starter)))
             "\\|")
            "\\)\\s *"))
-(c-lang-setvar comment-start-skip (c-lang-const comment-start-skip))
 
 (c-lang-defconst c-syntactic-ws-start
   ;; Regexp matching any sequence that can start syntactic whitespace.
@@ -1596,14 +1559,11 @@
   "Function to which beginning-of-defun-function will be set."
   t 'c-beginning-of-defun
   awk 'c-awk-beginning-of-defun)
-(c-lang-setvar beginning-of-defun-function
-              (c-lang-const beginning-of-defun-function))
 
 (c-lang-defconst end-of-defun-function
   "Function to which end-of-defun-function will be set."
   t 'c-end-of-defun
   awk 'c-awk-end-of-defun)
-(c-lang-setvar end-of-defun-function (c-lang-const end-of-defun-function))
 
 ;;; In-comment text handling.
 
@@ -2018,7 +1978,7 @@
   ;; ambiguous with types or type prefixes.  These are the keywords (like
   ;; extern, namespace, but NOT template) that can modify a declaration.
   t (c-make-keywords-re t
-      (set-difference (c-lang-const c-prefix-spec-kwds)
+      (cl-set-difference (c-lang-const c-prefix-spec-kwds)
                      (append (c-lang-const c-type-start-kwds)
                              (c-lang-const c-<>-arglist-kwds))
                      :test 'string-equal)))
@@ -2034,7 +1994,7 @@
   ;; Adorned regexp matching all keywords that can't appear at the
   ;; start of a declaration.
   t (c-make-keywords-re t
-      (set-difference (c-lang-const c-keywords)
+      (cl-set-difference (c-lang-const c-keywords)
                      (append (c-lang-const c-type-start-kwds)
                              (c-lang-const c-prefix-spec-kwds)
                              (c-lang-const c-typeof-kwds))
@@ -2044,7 +2004,7 @@
 
 (c-lang-defconst c-not-primitive-type-keywords
   "List of all keywords apart from primitive types (like \"int\")."
-  t (set-difference (c-lang-const c-keywords)
+  t (cl-set-difference (c-lang-const c-keywords)
                    (c-lang-const c-primitive-type-kwds)
                    :test 'string-equal)
   ;; The "more" for C++ is the QT keyword (as in "more slots:").
@@ -2431,10 +2391,10 @@
   t (let* ((decl-kwds (append (c-lang-const c-class-decl-kwds)
                              (c-lang-const c-other-block-decl-kwds)
                              (c-lang-const c-inexpr-class-kwds)))
-          (unambiguous (set-difference decl-kwds
+          (unambiguous (cl-set-difference decl-kwds
                                        (c-lang-const c-type-start-kwds)
                                        :test 'string-equal))
-          (ambiguous (intersection decl-kwds
+          (ambiguous (cl-intersection decl-kwds
                                    (c-lang-const c-type-start-kwds)
                                    :test 'string-equal)))
       (if ambiguous
@@ -2469,27 +2429,24 @@
 
 ;; Note: No `*-kwds' language constants may be defined below this point.
 
-(eval-and-compile
-  (defconst c-kwds-lang-consts
+(defconst c-kwds-lang-consts
     ;; List of all the language constants that contain keyword lists.
     (let (list)
       (mapatoms (lambda (sym)
-                 (when (and (boundp sym)
+                (when (and ;; (boundp sym)
                             (string-match "-kwds\\'" (symbol-name sym)))
                    ;; Make the list of globally interned symbols
                    ;; instead of ones interned in `c-lang-constants'.
                    (setq list (cons (intern (symbol-name sym)) list))))
                c-lang-constants)
-      list)))
+    list))
 
 (c-lang-defconst c-keywords
   ;; All keywords as a list.
   t (cl-delete-duplicates
-     (c-lang-defconst-eval-immediately
-      `(append ,@(mapcar (lambda (kwds-lang-const)
-                          `(c-lang-const ,kwds-lang-const))
-                        c-kwds-lang-consts)
-              nil))
+     (apply #'append (mapcar (lambda (kwds-lang-const)
+                              (c-get-lang-constant kwds-lang-const))
+                            c-kwds-lang-consts))
      :test 'string-equal))
 
 (c-lang-defconst c-keywords-regexp
@@ -2501,18 +2458,10 @@
   ;; An alist with all the keywords in the cars.  The cdr for each
   ;; keyword is a list of the symbols for the `*-kwds' lists that
   ;; contains it.
-  t (let ((kwd-list-alist
-          (c-lang-defconst-eval-immediately
-           `(list ,@(mapcar (lambda (kwds-lang-const)
-                              `(cons ',kwds-lang-const
-                                     (c-lang-const ,kwds-lang-const)))
-                            c-kwds-lang-consts))))
-         lang-const kwd-list kwd
+  t (let (kwd-list kwd
          result-alist elem)
-      (while kwd-list-alist
-       (setq lang-const (caar kwd-list-alist)
-             kwd-list (cdar kwd-list-alist)
-             kwd-list-alist (cdr kwd-list-alist))
+      (dolist (lang-const c-kwds-lang-consts)
+       (setq kwd-list (c-get-lang-constant lang-const))
        (while kwd-list
          (setq kwd (car kwd-list)
                kwd-list (cdr kwd-list))
@@ -2560,7 +2509,7 @@
   ;; Adorned regexp matching all keywords that should be fontified
   ;; with the keywords face.  I.e. that aren't types or constants.
   t (c-make-keywords-re t
-      (set-difference (c-lang-const c-keywords)
+      (cl-set-difference (c-lang-const c-keywords)
                      (append (c-lang-const c-primitive-type-kwds)
                              (c-lang-const c-constant-kwds))
                      :test 'string-equal)))
@@ -2598,12 +2547,13 @@
                            right-assoc-sequence)
                          t))
 
-          (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops
-                                                  in-or-postfix-ops
-                                                  :test 'string-equal))
-          (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops
-                                              in-or-postfix-ops
-                                              :test 'string-equal)))
+          ;; (unambiguous-prefix-ops (cl-set-difference nonkeyword-prefix-ops
+          ;;                                      in-or-postfix-ops
+          ;;                                      :test 'string-equal))
+          ;; (ambiguous-prefix-ops (cl-intersection nonkeyword-prefix-ops
+          ;;                                  in-or-postfix-ops
+          ;;                                  :test 'string-equal))
+           )
 
       (concat
        "\\("
@@ -2611,13 +2561,13 @@
        ;; first submatch from them together with `c-primary-expr-kwds'.
        (c-make-keywords-re t
         (append (c-lang-const c-primary-expr-kwds)
-                (set-difference prefix-ops nonkeyword-prefix-ops
+                (cl-set-difference prefix-ops nonkeyword-prefix-ops
                                 :test 'string-equal)))
 
        "\\|"
        ;; Match all ambiguous operators.
        (c-make-keywords-re nil
-        (intersection nonkeyword-prefix-ops in-or-postfix-ops
+        (cl-intersection nonkeyword-prefix-ops in-or-postfix-ops
                       :test 'string-equal))
        "\\)"
 
@@ -2633,7 +2583,7 @@
        "\\|"
        ;; The unambiguous operators from `prefix-ops'.
        (c-make-keywords-re nil
-        (set-difference nonkeyword-prefix-ops in-or-postfix-ops
+        (cl-set-difference nonkeyword-prefix-ops in-or-postfix-ops
                         :test 'string-equal))
 
        "\\|"
@@ -2779,7 +2729,7 @@
 
   ;; Default to all chars that only occurs in nonsymbol tokens outside
   ;; identifiers.
-  t (set-difference
+  t (cl-set-difference
      (c-lang-const c-nonsymbol-token-char-list)
      (c-filter-ops (append (c-lang-const c-identifier-ops)
                           (list (cons nil
@@ -2796,25 +2746,25 @@
 
   ;; Allow cpp operations (where applicable).
   t (if (c-lang-const c-opt-cpp-prefix)
-       (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+       (cl-set-difference (c-lang-const c-block-prefix-disallowed-chars)
                        '(?#))
       (c-lang-const c-block-prefix-disallowed-chars))
 
   ;; Allow ':' for inherit list starters.
-  (c++ objc idl) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+  (c++ objc idl) (cl-set-difference (c-lang-const 
c-block-prefix-disallowed-chars)
                                 '(?:))
 
   ;; Allow ',' for multiple inherits.
-  (c++ java) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+  (c++ java) (cl-set-difference (c-lang-const c-block-prefix-disallowed-chars)
                             '(?,))
 
   ;; Allow parentheses for anonymous inner classes in Java and class
   ;; initializer lists in Pike.
-  (java pike) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+  (java pike) (cl-set-difference (c-lang-const c-block-prefix-disallowed-chars)
                              '(?\( ?\)))
 
   ;; Allow '"' for extern clauses (e.g. extern "C" {...}).
-  (c c++ objc) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+  (c c++ objc) (cl-set-difference (c-lang-const 
c-block-prefix-disallowed-chars)
                               '(?\" ?')))
 
 (c-lang-defconst c-block-prefix-charset
@@ -3121,7 +3071,7 @@
   t (concat
      ;; All keywords except `c-label-kwds' and `c-protection-kwds'.
      (c-make-keywords-re t
-       (set-difference (c-lang-const c-keywords)
+       (cl-set-difference (c-lang-const c-keywords)
                       (append (c-lang-const c-label-kwds)
                               (c-lang-const c-protection-kwds))
                       :test 'string-equal)))
@@ -3201,123 +3151,47 @@
 
 ;;; Wrap up the `c-lang-defvar' system.
 
-;; Compile in the list of language variables that has been collected
-;; with the `c-lang-defvar' and `c-lang-setvar' macros.  Note that the
-;; first element of each is nil.
-(defconst c-lang-variable-inits (cc-eval-when-compile c-lang-variable-inits))
-(defconst c-emacs-variable-inits (cc-eval-when-compile c-emacs-variable-inits))
-
-;; Make the `c-lang-setvar' variables buffer local in the current buffer.
-;; These are typically standard emacs variables such as `comment-start'.
-(defmacro c-make-emacs-variables-local ()
-  `(progn
-     ,@(mapcar (lambda (init)
-                `(make-local-variable ',(car init)))
-              (cdr c-emacs-variable-inits))))
-
-(defun c-make-init-lang-vars-fun (mode)
-  "Create a function that initializes all the language dependent variables
-for the given mode.
-
-This function should be evaluated at compile time, so that the
-function it returns is byte compiled with all the evaluated results
-from the language constants.  Use the `c-init-language-vars' macro to
-accomplish that conveniently."
-
-  (if (and (not load-in-progress)
-          (boundp 'byte-compile-dest-file)
-          (stringp byte-compile-dest-file))
-
-      ;; No need to byte compile this lambda since the byte compiler is
-      ;; smart enough to detect the `funcall' construct in the
-      ;; `c-init-language-vars' macro below and compile it all straight
-      ;; into the function that contains `c-init-language-vars'.
-      `(lambda ()
-
-        ;; This let sets up the context for `c-mode-var' and similar
-        ;; that could be in the result from `macroexpand-all'.
-        (let ((c-buffer-is-cc-mode ',mode)
-              current-var source-eval)
-          (c-make-emacs-variables-local)
-          (condition-case err
-
-              (if (eq c-version-sym ',c-version-sym)
-                  (setq ,@(let ((c-buffer-is-cc-mode mode)
-                                (c-lang-const-expansion 'immediate))
-                            ;; `c-lang-const' will expand to the evaluated
-                            ;; constant immediately in `macroexpand-all'
-                            ;; below.
-                             (cl-mapcan
-                              (lambda (init)
-                                `(current-var ',(car init)
-                                  ,(car init) ,(macroexpand-all
-                                                (elt init 1))))
-                              ;; Note: The following `append' copies the
-                              ;; first argument.  That list is small, so
-                              ;; this doesn't matter too much.
-                             (append (cdr c-emacs-variable-inits)
-                                     (cdr c-lang-variable-inits)))))
-
-                ;; This diagnostic message isn't useful for end
-                ;; users, so it's disabled.
-                ;;(unless (get ',mode 'c-has-warned-lang-consts)
-                ;;  (message ,(concat "%s compiled with CC Mode %s "
-                ;;                    "but loaded with %s - evaluating "
-                ;;                    "language constants from source")
-                ;;           ',mode ,c-version c-version)
-                ;;  (put ',mode 'c-has-warned-lang-consts t))
-
-                (setq source-eval t)
-                (let ((init ',(append (cdr c-emacs-variable-inits)
-                                      (cdr c-lang-variable-inits))))
-                  (while init
-                    (setq current-var (caar init))
-                    (set (caar init) (eval (cadar init)))
-                    (setq init (cdr init)))))
-
-            (error
-             (if current-var
-                 (message "Eval error in the `c-lang-defvar' or 
`c-lang-setvar' for `%s'%s: %S"
-                          current-var
-                          (if source-eval
-                              (format "\
- (fallback source eval - %s compiled with CC Mode %s but loaded with %s)"
-                                      ',mode ,c-version c-version)
-                            "")
-                          err)
-               (signal (car err) (cdr err)))))))
+(eval-when-compile
+  (unless (fboundp 'setq-local)
+    (defmacro setq-local (var val)
+      "Set variable VAR to value VAL in current buffer."
+      ;; Can't use backquote here, it's too early in the bootstrap.
+      (list 'set (list 'make-local-variable (list 'quote var)) val))))
+
+(defun c-emacs-variable-inits ()
+  (setq-local comment-start (c-lang-const comment-start))
+  (setq-local comment-end (c-lang-const comment-end))
+  (setq-local comment-start-skip (c-lang-const comment-start-skip))
+  (setq-local beginning-of-defun-function
+              (c-lang-const beginning-of-defun-function))
+  (setq-local end-of-defun-function (c-lang-const end-of-defun-function)))
 
-    ;; Being evaluated from source.  Always use the dynamic method to
-    ;; work well when `c-lang-defvar's in this file are reevaluated
-    ;; interactively.
-    `(lambda ()
-       (require 'cc-langs)
-       (let ((c-buffer-is-cc-mode ',mode)
-            (init (append (cdr c-emacs-variable-inits)
-                          (cdr c-lang-variable-inits)))
+(defun c-init-language-vars-for (mode)
+  "Initialize all the language dependent variables for the given mode."
+  (let ((c-buffer-is-cc-mode mode)
             current-var)
-        (c-make-emacs-variables-local)
+    (c-emacs-variable-inits)
         (condition-case err
-
-            (while init
-              (setq current-var (caar init))
-              (set (caar init) (eval (cadar init)))
-              (setq init (cdr init)))
-
+        (dolist (var c-lang--vars)
+          (setq current-var var)
+          (set (make-local-variable var)
+               (let ((f (get var 'c-initialize-function)))
+                 (if f (funcall f)
+                   (c-get-lang-constant var)))))
           (error
            (if current-var
                (message
-                "Eval error in the `c-lang-defvar' or `c-lang-setver' for `%s' 
(source eval): %S"
+            "Eval error in the `c-lang-defvar' for `%s': %S"
                 current-var err)
              (signal (car err) (cdr err)))))))
-    ))
 
 (defmacro c-init-language-vars (mode)
   "Initialize all the language dependent variables for the given mode.
 This macro is expanded at compile time to a form tailored for the mode
 in question, so MODE must be a constant.  Therefore MODE is not
 evaluated and should not be quoted."
-  `(funcall ,(c-make-init-lang-vars-fun mode)))
+  (declare (obsolete c-init-language-vars-for "24.5"))
+  `(c-init-language-vars-for ',mode))
 
 
 (cc-provide 'cc-langs)

=== modified file 'lisp/progmodes/cc-mode.el'
--- lisp/progmodes/cc-mode.el   2014-03-04 04:03:34 +0000
+++ lisp/progmodes/cc-mode.el   2014-09-08 16:35:55 +0000
@@ -95,14 +95,9 @@
 (cc-require 'cc-menus)
 (cc-require 'cc-guess)
 
-;; Silence the compiler.
-(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
-(cc-bytecomp-defun run-mode-hooks)     ; Emacs 21.1
-
 ;; We set these variables during mode init, yet we don't require
 ;; font-lock.
-(cc-bytecomp-defvar font-lock-defaults)
-(cc-bytecomp-defvar font-lock-syntactic-keywords)
+(defvar font-lock-defaults)
 
 ;; Menu support for both XEmacs and Emacs.  If you don't have easymenu
 ;; with your version of Emacs, you are incompatible!
@@ -149,21 +144,6 @@
 (defun c-leave-cc-mode-mode ()
   (setq c-buffer-is-cc-mode nil))
 
-(defun c-init-language-vars-for (mode)
-  "Initialize the language variables for one of the language modes
-directly supported by CC Mode.  This can be used instead of the
-`c-init-language-vars' macro if the language you want to use is one of
-those, rather than a derived language defined through the language
-variable system (see \"cc-langs.el\")."
-  (cond ((eq mode 'c-mode)    (c-init-language-vars c-mode))
-       ((eq mode 'c++-mode)  (c-init-language-vars c++-mode))
-       ((eq mode 'objc-mode) (c-init-language-vars objc-mode))
-       ((eq mode 'java-mode) (c-init-language-vars java-mode))
-       ((eq mode 'idl-mode)  (c-init-language-vars idl-mode))
-       ((eq mode 'pike-mode) (c-init-language-vars pike-mode))
-       ((eq mode 'awk-mode)  (c-init-language-vars awk-mode))
-       (t (error "Unsupported mode %s" mode))))
-
 ;;;###autoload
 (defun c-initialize-cc-mode (&optional new-style-init)
   "Initialize CC Mode for use in the current buffer.
@@ -816,7 +796,7 @@
 (defmacro c-run-mode-hooks (&rest hooks)
   ;; Emacs 21.1 has introduced a system with delayed mode hooks that
   ;; requires the use of the new function `run-mode-hooks'.
-  (if (cc-bytecomp-fboundp 'run-mode-hooks)
+  (if (fboundp 'run-mode-hooks)
       `(run-mode-hooks ,@hooks)
     `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks))))
 
@@ -1232,8 +1212,8 @@
          (font-lock-mark-block-function
           . c-mark-function)))
 
-  (make-local-variable 'font-lock-fontify-region-function)
-  (setq font-lock-fontify-region-function 'c-font-lock-fontify-region)
+  (set (make-local-variable 'font-lock-fontify-region-function)
+       #'c-font-lock-fontify-region)
 
   (if (featurep 'xemacs)
       (make-local-hook 'font-lock-mode-hook))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]