Finish fixing a cacheing bug in CC Mode (see 2016-03-09)

* lisp/progmodes/cc-cmds.el: (c-beginning-of-defun, c-end-of-defun): Remove
superfluous invocations of c-self-bind-state-cache.

* lisp/progmodes/cc-defs.el: (c-self-bind-state-cache): Copy and terminate
markers correctly.

* lisp/progmodes/cc-engine.el (c-record-parse-state-state): Terminate stale
markers.
This commit is contained in:
Alan Mackenzie 2016-03-30 17:14:03 +00:00
parent ed19f20744
commit 2244331218
3 changed files with 144 additions and 128 deletions

View file

@ -1594,70 +1594,69 @@ defun."
(c-region-is-active-p) (c-region-is-active-p)
(push-mark)) (push-mark))
(c-self-bind-state-cache ; We must not share with other users of c-state-cache. (c-save-buffer-state
(c-save-buffer-state (beginning-of-defun-function
(beginning-of-defun-function end-of-defun-function
end-of-defun-function (start (point))
(start (point)) (paren-state (c-parse-state))
(paren-state (c-parse-state)) (orig-point-min (point-min)) (orig-point-max (point-max))
(orig-point-min (point-min)) (orig-point-max (point-max)) lim ; Position of { which has been widened to.
lim ; Position of { which has been widened to. where pos case-fold-search)
where pos case-fold-search)
(save-restriction (save-restriction
(if (eq c-defun-tactic 'go-outward) (if (eq c-defun-tactic 'go-outward)
(setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace. (setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace.
paren-state orig-point-min orig-point-max))) paren-state orig-point-min orig-point-max)))
;; Move back out of any macro/comment/string we happen to be in. ;; Move back out of any macro/comment/string we happen to be in.
(c-beginning-of-macro) (c-beginning-of-macro)
(setq pos (c-literal-limits)) (setq pos (c-literal-limits))
(if pos (goto-char (car pos))) (if pos (goto-char (car pos)))
(setq where (c-where-wrt-brace-construct)) (setq where (c-where-wrt-brace-construct))
(if (< arg 0) (if (< arg 0)
;; Move forward to the closing brace of a function. ;; Move forward to the closing brace of a function.
(progn (progn
(if (memq where '(at-function-end outwith-function)) (if (memq where '(at-function-end outwith-function))
(setq arg (1+ arg))) (setq arg (1+ arg)))
(if (< arg 0) (if (< arg 0)
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(< (setq arg (- (c-forward-to-nth-EOF-} (- arg) where))) 0))) (< (setq arg (- (c-forward-to-nth-EOF-} (- arg) where))) 0)))
;; Move forward to the next opening brace.... ;; Move forward to the next opening brace....
(when (and (= arg 0) (when (and (= arg 0)
(progn (progn
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(not (c-syntactic-re-search-forward "{" nil 'eob))) (not (c-syntactic-re-search-forward "{" nil 'eob)))
(eq (char-before) ?{))) (eq (char-before) ?{)))
(backward-char) (backward-char)
;; ... and backward to the function header. ;; ... and backward to the function header.
(c-beginning-of-decl-1) (c-beginning-of-decl-1)
t)) t))
;; Move backward to the opening brace of a function, making successively ;; Move backward to the opening brace of a function, making successively
;; larger portions of the buffer visible as necessary. ;; larger portions of the buffer visible as necessary.
(when (> arg 0) (when (> arg 0)
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(> (setq arg (c-backward-to-nth-BOF-{ arg where)) 0))) (> (setq arg (c-backward-to-nth-BOF-{ arg where)) 0)))
(when (eq arg 0) (when (eq arg 0)
;; Go backward to this function's header. ;; Go backward to this function's header.
(c-beginning-of-decl-1) (c-beginning-of-decl-1)
(setq pos (point)) (setq pos (point))
;; We're now there, modulo comments and whitespace. ;; We're now there, modulo comments and whitespace.
;; Try to be line oriented; position point at the closest ;; Try to be line oriented; position point at the closest
;; preceding boi that isn't inside a comment, but if we hit ;; preceding boi that isn't inside a comment, but if we hit
;; the previous declaration then we use the current point ;; the previous declaration then we use the current point
;; instead. ;; instead.
(while (and (/= (point) (c-point 'boi)) (while (and (/= (point) (c-point 'boi))
(c-backward-single-comment))) (c-backward-single-comment)))
(if (/= (point) (c-point 'boi)) (if (/= (point) (c-point 'boi))
(goto-char pos))) (goto-char pos)))
(c-keep-region-active) (c-keep-region-active)
(= arg 0)))))) (= arg 0)))))
(defun c-forward-to-nth-EOF-} (n where) (defun c-forward-to-nth-EOF-} (n where)
;; Skip to the closing brace of the Nth function after point. If ;; Skip to the closing brace of the Nth function after point. If
@ -1719,68 +1718,66 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
(c-region-is-active-p) (c-region-is-active-p)
(push-mark)) (push-mark))
(c-self-bind-state-cache ; c-state-cache's list structure must not be shared (c-save-buffer-state
; with other users. (beginning-of-defun-function
(c-save-buffer-state end-of-defun-function
(beginning-of-defun-function (start (point))
end-of-defun-function (paren-state (c-parse-state))
(start (point)) (orig-point-min (point-min)) (orig-point-max (point-max))
(paren-state (c-parse-state)) lim
(orig-point-min (point-min)) (orig-point-max (point-max)) where pos case-fold-search)
lim
where pos case-fold-search)
(save-restriction (save-restriction
(if (eq c-defun-tactic 'go-outward) (if (eq c-defun-tactic 'go-outward)
(setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace (setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace
paren-state orig-point-min orig-point-max))) paren-state orig-point-min orig-point-max)))
;; Move back out of any macro/comment/string we happen to be in. ;; Move back out of any macro/comment/string we happen to be in.
(c-beginning-of-macro) (c-beginning-of-macro)
(setq pos (c-literal-limits)) (setq pos (c-literal-limits))
(if pos (goto-char (car pos))) (if pos (goto-char (car pos)))
(setq where (c-where-wrt-brace-construct)) (setq where (c-where-wrt-brace-construct))
(if (< arg 0) (if (< arg 0)
;; Move backwards to the } of a function ;; Move backwards to the } of a function
(progn (progn
(if (memq where '(at-header outwith-function)) (if (memq where '(at-header outwith-function))
(setq arg (1+ arg))) (setq arg (1+ arg)))
(if (< arg 0) (if (< arg 0)
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(< (setq arg (- (c-backward-to-nth-BOF-{ (- arg) where))) 0))) (< (setq arg (- (c-backward-to-nth-BOF-{ (- arg) where))) 0)))
(if (= arg 0) (if (= arg 0)
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(progn (c-syntactic-skip-backward "^}") (progn (c-syntactic-skip-backward "^}")
(not (eq (char-before) ?})))))) (not (eq (char-before) ?}))))))
;; Move forward to the } of a function ;; Move forward to the } of a function
(if (> arg 0) (if (> arg 0)
(c-while-widening-to-decl-block (c-while-widening-to-decl-block
(> (setq arg (c-forward-to-nth-EOF-} arg where)) 0)))) (> (setq arg (c-forward-to-nth-EOF-} arg where)) 0))))
;; Do we need to move forward from the brace to the semicolon? ;; Do we need to move forward from the brace to the semicolon?
(when (eq arg 0) (when (eq arg 0)
(if (c-in-function-trailer-p) ; after "}" of struct/enum, etc. (if (c-in-function-trailer-p) ; after "}" of struct/enum, etc.
(c-syntactic-re-search-forward ";")) (c-syntactic-re-search-forward ";"))
(setq pos (point)) (setq pos (point))
;; We're there now, modulo comments and whitespace. ;; We're there now, modulo comments and whitespace.
;; Try to be line oriented; position point after the next ;; Try to be line oriented; position point after the next
;; newline that isn't inside a comment, but if we hit the ;; newline that isn't inside a comment, but if we hit the
;; next declaration then we use the current point instead. ;; next declaration then we use the current point instead.
(while (and (not (bolp)) (while (and (not (bolp))
(not (looking-at "\\s *$")) (not (looking-at "\\s *$"))
(c-forward-single-comment))) (c-forward-single-comment)))
(cond ((bolp)) (cond ((bolp))
((looking-at "\\s *$") ((looking-at "\\s *$")
(forward-line 1)) (forward-line 1))
(t (t
(goto-char pos)))) (goto-char pos))))
(c-keep-region-active) (c-keep-region-active)
(= arg 0))))) (= arg 0))))
(defun c-defun-name () (defun c-defun-name ()
"Return the name of the current defun, or NIL if there isn't one. "Return the name of the current defun, or NIL if there isn't one.

View file

@ -1400,25 +1400,41 @@ been put there by c-put-char-property. POINT remains unchanged."
(c-set-cpp-delimiters ,beg ,end))))) (c-set-cpp-delimiters ,beg ,end)))))
(defmacro c-self-bind-state-cache (&rest forms) (defmacro c-self-bind-state-cache (&rest forms)
;; Bind the state cache to itself and execute the FORMS. It is assumed that no ;; Bind the state cache to itself and execute the FORMS. Return the result
;; buffer changes will happen in FORMS, and no hidden buffer changes which could ;; of the last FORM executed. It is assumed that no buffer changes will
;; affect the parsing will be made by FORMS. ;; happen in FORMS, and no hidden buffer changes which could affect the
`(let ((c-state-cache (copy-tree c-state-cache)) ;; parsing will be made by FORMS.
(c-state-cache-good-pos c-state-cache-good-pos) `(let* ((c-state-cache (copy-tree c-state-cache))
;(c-state-nonlit-pos-cache (copy-tree c-state-nonlit-pos-cache)) (c-state-cache-good-pos c-state-cache-good-pos)
;(c-state-nonlit-pos-cache-limit c-state-nonlit-pos-cache-limit) ;(c-state-nonlit-pos-cache (copy-tree c-state-nonlit-pos-cache))
;(c-state-semi-nonlit-pos-cache (copy-tree c-state-semi-nonlit-pos-cache)) ;(c-state-nonlit-pos-cache-limit c-state-nonlit-pos-cache-limit)
;(c-state-semi-nonlit-pos-cache-limit c-state-semi-nonlit-pos-cache) ;(c-state-semi-nonlit-pos-cache (copy-tree c-state-semi-nonlit-pos-cache))
(c-state-brace-pair-desert (copy-tree c-state-brace-pair-desert)) ;(c-state-semi-nonlit-pos-cache-limit c-state-semi-nonlit-pos-cache)
(c-state-point-min c-state-point-min) (c-state-brace-pair-desert (copy-tree c-state-brace-pair-desert))
(c-state-point-min-lit-type c-state-point-min-lit-type) (c-state-point-min c-state-point-min)
(c-state-point-min-lit-start c-state-point-min-lit-start) (c-state-point-min-lit-type c-state-point-min-lit-type)
(c-state-min-scan-pos c-state-min-scan-pos) (c-state-point-min-lit-start c-state-point-min-lit-start)
(c-state-old-cpp-beg c-state-old-cpp-beg) (c-state-min-scan-pos c-state-min-scan-pos)
(c-state-old-cpp-end c-state-old-cpp-end)) (c-state-old-cpp-beg-marker (if (markerp c-state-old-cpp-beg-marker)
,@forms)) (copy-marker c-state-old-cpp-beg-marker)
c-state-old-cpp-beg-marker))
(c-state-old-cpp-beg (if (markerp c-state-old-cpp-beg)
c-state-old-cpp-beg-marker
c-state-old-cpp-beg))
(c-state-old-cpp-end-marker (if (markerp c-state-old-cpp-end-marker)
(copy-marker c-state-old-cpp-end-marker)
c-state-old-cpp-end-marker))
(c-state-old-cpp-end (if (markerp c-state-old-cpp-end)
c-state-old-cpp-end-marker
c-state-old-cpp-end))
(c-parse-state-state c-parse-state-state))
(prog1
(progn ,@forms)
(if (markerp c-state-old-cpp-beg-marker)
(move-marker c-state-old-cpp-beg-marker nil))
(if (markerp c-state-old-cpp-end-marker)
(move-marker c-state-old-cpp-end-marker nil)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The following macros are to be used only in `c-parse-state' and its ;; The following macros are to be used only in `c-parse-state' and its
;; subroutines. Their main purpose is to simplify the handling of C++/Java ;; subroutines. Their main purpose is to simplify the handling of C++/Java

View file

@ -3472,6 +3472,9 @@ comment at the start of cc-engine.el for more info."
(make-variable-buffer-local 'c-parse-state-state) (make-variable-buffer-local 'c-parse-state-state)
(defun c-record-parse-state-state () (defun c-record-parse-state-state ()
(setq c-parse-state-point (point)) (setq c-parse-state-point (point))
(when (markerp (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)))
(move-marker (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)) nil)
(move-marker (cdr (assq 'c-state-old-cpp-end c-parse-state-state)) nil))
(setq c-parse-state-state (setq c-parse-state-state
(mapcar (mapcar
(lambda (arg) (lambda (arg)