aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2012-11-21 20:41:03 +0000
committerAlan Mackenzie2012-11-21 20:41:03 +0000
commitb03aabdac594c3c6fd587ad4927bc4187fa12c2d (patch)
treeabd267edc2b04a9ca859bc6bb5c160a5f4132316
parentcb5867b1f8af39ffd70767fc06fd364bca67e968 (diff)
downloademacs-b03aabdac594c3c6fd587ad4927bc4187fa12c2d.tar.gz
emacs-b03aabdac594c3c6fd587ad4927bc4187fa12c2d.zip
Fix bugs in the CC Mode state cache. Enhance a debugging mechanism.
-rw-r--r--lisp/ChangeLog17
-rw-r--r--lisp/progmodes/cc-engine.el53
-rw-r--r--lisp/progmodes/cc-mode.el7
3 files changed, 65 insertions, 12 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8502cd477e9..e60e9b49043 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,20 @@
12012-11-21 Alan Mackenzie <acm@muc.de>
2
3 Fix bugs in the state cache. Enhance a debugging mechanism.
4 * progmodes/cc-engine.el (c-parse-state-get-strategy): Don't use
5 "brace at column zero" strategy for C++.
6 (c-append-lower-brace-pair-to-state-cache): Repair algorithm.
7 (c-parse-state-point): New variable.
8 (c-record-parse-state-state): Record old parse state with
9 `copy-tree'. Record previous value of point.
10 (c-debug-parse-state-double-cons): New debugging function.
11 (c-debug-parse-state): Call the above new function.
12 (c-toggle-parse-state-debug): Output a confirmatory message.
13
14 * progmodes/cc-mode.el (c-before-change, c-after-change): Call
15 c-invalidate-state-cache from `c-before-change' instead of
16 `c-after-change'.
17
12012-11-20 Daniel Colascione <dancol@dancol.org> 182012-11-20 Daniel Colascione <dancol@dancol.org>
2 19
3 * term/w32-win.el (cygwin-convert-path-from-windows): Accomodate 20 * term/w32-win.el (cygwin-convert-path-from-windows): Accomodate
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 2aa04cb2b0b..10355451480 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -2561,8 +2561,11 @@ comment at the start of cc-engine.el for more info."
2561 start-point cache-pos))) 2561 start-point cache-pos)))
2562 2562
2563 ;; Might we be better off starting from the top level, two defuns back, 2563 ;; Might we be better off starting from the top level, two defuns back,
2564 ;; instead? 2564 ;; instead? This heuristic no longer works well in C++, where
2565 (when (> how-far c-state-cache-too-far) 2565 ;; declarations inside namespace brace blocks are frequently placed at
2566 ;; column zero.
2567 (when (and (not (c-major-mode-is 'c++-mode))
2568 (> how-far c-state-cache-too-far))
2566 (setq BOD-pos (c-get-fallback-scan-pos here)) ; somewhat EXPENSIVE!!! 2569 (setq BOD-pos (c-get-fallback-scan-pos here)) ; somewhat EXPENSIVE!!!
2567 (if (< (- here BOD-pos) how-far) 2570 (if (< (- here BOD-pos) how-far)
2568 (setq strategy 'BOD 2571 (setq strategy 'BOD
@@ -2649,17 +2652,20 @@ comment at the start of cc-engine.el for more info."
2649 ;; If we're essentially repeating a fruitless search, just give up. 2652 ;; If we're essentially repeating a fruitless search, just give up.
2650 (unless (and c-state-brace-pair-desert 2653 (unless (and c-state-brace-pair-desert
2651 (eq cache-pos (car c-state-brace-pair-desert)) 2654 (eq cache-pos (car c-state-brace-pair-desert))
2655 (or (null (car c-state-brace-pair-desert))
2656 (> from (car c-state-brace-pair-desert)))
2652 (<= from (cdr c-state-brace-pair-desert))) 2657 (<= from (cdr c-state-brace-pair-desert)))
2653 ;; DESERT-LIM. Only search what we absolutely need to, 2658 ;; DESERT-LIM. Avoid repeated searching through the cached desert.
2654 (let ((desert-lim 2659 (let ((desert-lim
2655 (and c-state-brace-pair-desert 2660 (and c-state-brace-pair-desert
2656 (eq cache-pos (car c-state-brace-pair-desert)) 2661 (eq cache-pos (car c-state-brace-pair-desert))
2662 (>= from (cdr c-state-brace-pair-desert))
2657 (cdr c-state-brace-pair-desert))) 2663 (cdr c-state-brace-pair-desert)))
2658 ;; CACHE-LIM. This limit will be necessary when an opening 2664 ;; CACHE-LIM. This limit will be necessary when an opening
2659 ;; paren at `cache-pos' has just had its matching close paren 2665 ;; paren at `cache-pos' has just had its matching close paren
2660 ;; inserted. `cache-pos' continues to be a search bound, even 2666 ;; inserted into the buffer. `cache-pos' continues to be a
2661 ;; though the algorithm below would skip over the new paren 2667 ;; search bound, even though the algorithm below would skip
2662 ;; pair. 2668 ;; over the new paren pair.
2663 (cache-lim (and cache-pos (< cache-pos from) cache-pos))) 2669 (cache-lim (and cache-pos (< cache-pos from) cache-pos)))
2664 (narrow-to-region 2670 (narrow-to-region
2665 (cond 2671 (cond
@@ -3342,12 +3348,18 @@ comment at the start of cc-engine.el for more info."
3342 (fset 'c-real-parse-state (symbol-function 'c-parse-state))) 3348 (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
3343(cc-bytecomp-defun c-real-parse-state) 3349(cc-bytecomp-defun c-real-parse-state)
3344 3350
3351(defvar c-parse-state-point nil)
3345(defvar c-parse-state-state nil) 3352(defvar c-parse-state-state nil)
3346(defun c-record-parse-state-state () 3353(defun c-record-parse-state-state ()
3354 (setq c-parse-state-point (point))
3347 (setq c-parse-state-state 3355 (setq c-parse-state-state
3348 (mapcar 3356 (mapcar
3349 (lambda (arg) 3357 (lambda (arg)
3350 (cons arg (symbol-value arg))) 3358 (let ((val (symbol-value arg)))
3359 (cons arg
3360 (if (consp val)
3361 (copy-tree val)
3362 val))))
3351 '(c-state-cache 3363 '(c-state-cache
3352 c-state-cache-good-pos 3364 c-state-cache-good-pos
3353 c-state-nonlit-pos-cache 3365 c-state-nonlit-pos-cache
@@ -3360,7 +3372,8 @@ comment at the start of cc-engine.el for more info."
3360 c-state-point-min-lit-start 3372 c-state-point-min-lit-start
3361 c-state-min-scan-pos 3373 c-state-min-scan-pos
3362 c-state-old-cpp-beg 3374 c-state-old-cpp-beg
3363 c-state-old-cpp-end)))) 3375 c-state-old-cpp-end
3376 c-parse-state-point))))
3364(defun c-replay-parse-state-state () 3377(defun c-replay-parse-state-state ()
3365 (message 3378 (message
3366 (concat "(setq " 3379 (concat "(setq "
@@ -3370,6 +3383,16 @@ comment at the start of cc-engine.el for more info."
3370 c-parse-state-state " ") 3383 c-parse-state-state " ")
3371 ")"))) 3384 ")")))
3372 3385
3386(defun c-debug-parse-state-double-cons (state)
3387 (let (state-car conses-not-ok)
3388 (while state
3389 (setq state-car (car state)
3390 state (cdr state))
3391 (if (and (consp state-car)
3392 (consp (car state)))
3393 (setq conses-not-ok t)))
3394 conses-not-ok))
3395
3373(defun c-debug-parse-state () 3396(defun c-debug-parse-state ()
3374 (let ((here (point)) (res1 (c-real-parse-state)) res2) 3397 (let ((here (point)) (res1 (c-real-parse-state)) res2)
3375 (let ((c-state-cache nil) 3398 (let ((c-state-cache nil)
@@ -3402,8 +3425,16 @@ comment at the start of cc-engine.el for more info."
3402 here res1 res2) 3425 here res1 res2)
3403 (message "Old state:") 3426 (message "Old state:")
3404 (c-replay-parse-state-state)) 3427 (c-replay-parse-state-state))
3428
3429 (when (c-debug-parse-state-double-cons res1)
3430 (message "c-parse-state INVALIDITY at %s: %s"
3431 here res1)
3432 (message "Old state:")
3433 (c-replay-parse-state-state))
3434
3405 (c-record-parse-state-state) 3435 (c-record-parse-state-state)
3406 res1)) 3436 res2 ; res1 correct a cascading series of errors ASAP
3437 ))
3407 3438
3408(defun c-toggle-parse-state-debug (&optional arg) 3439(defun c-toggle-parse-state-debug (&optional arg)
3409 (interactive "P") 3440 (interactive "P")
@@ -3411,7 +3442,9 @@ comment at the start of cc-engine.el for more info."
3411 (fset 'c-parse-state (symbol-function (if c-debug-parse-state 3442 (fset 'c-parse-state (symbol-function (if c-debug-parse-state
3412 'c-debug-parse-state 3443 'c-debug-parse-state
3413 'c-real-parse-state))) 3444 'c-real-parse-state)))
3414 (c-keep-region-active)) 3445 (c-keep-region-active)
3446 (message "c-debug-parse-state %sabled"
3447 (if c-debug-parse-state "en" "dis")))
3415(when c-debug-parse-state 3448(when c-debug-parse-state
3416 (c-toggle-parse-state-debug 1)) 3449 (c-toggle-parse-state-debug 1))
3417 3450
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 50eaebe4dec..91866278e28 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1034,7 +1034,10 @@ Note that the style variables are always made local to the buffer."
1034 (mapc (lambda (fn) 1034 (mapc (lambda (fn)
1035 (funcall fn beg end)) 1035 (funcall fn beg end))
1036 c-get-state-before-change-functions)) 1036 c-get-state-before-change-functions))
1037 )))) 1037 )))
1038 ;; The following must be done here rather than in `c-after-change' because
1039 ;; newly inserted parens would foul up the invalidation algorithm.
1040 (c-invalidate-state-cache beg))
1038 1041
1039(defvar c-in-after-change-fontification nil) 1042(defvar c-in-after-change-fontification nil)
1040(make-variable-buffer-local 'c-in-after-change-fontification) 1043(make-variable-buffer-local 'c-in-after-change-fontification)
@@ -1082,7 +1085,7 @@ Note that the style variables are always made local to the buffer."
1082 1085
1083 (c-trim-found-types beg end old-len) ; maybe we don't need all of these. 1086 (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
1084 (c-invalidate-sws-region-after beg end) 1087 (c-invalidate-sws-region-after beg end)
1085 (c-invalidate-state-cache beg) 1088 ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
1086 (c-invalidate-find-decl-cache beg) 1089 (c-invalidate-find-decl-cache beg)
1087 1090
1088 (when c-recognize-<>-arglists 1091 (when c-recognize-<>-arglists