aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/cc-engine.el215
-rw-r--r--lisp/progmodes/cc-mode.el45
2 files changed, 186 insertions, 74 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index a2762ca2097..a25d0595535 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -2526,6 +2526,25 @@ comment at the start of cc-engine.el for more info."
2526;; reduced by buffer changes, and increased by invocations of 2526;; reduced by buffer changes, and increased by invocations of
2527;; `c-state-literal-at'. 2527;; `c-state-literal-at'.
2528 2528
2529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2530;; We also maintain a less simple cache of positions which aren't in a
2531;; literal, disregarding macros.
2532;;
2533;; This cache is in two parts: the "near" cache, which is an association list
2534;; of a small number (currently six) of positions and the parser states there;
2535;; the "far" cache (also known as "the cache"), a list of compressed parser
2536;; states going back to the beginning of the buffer, one entry every 3000
2537;; characters.
2538;;
2539;; When searching this cache, `c-state-semi-pp-to-literal' first seeks an
2540;; exact match, then a "close" match from the near cache. If neither of these
2541;; succeed, the nearest entry in the far cache is used.
2542;;
2543;; Because either sub-cache can raise `c-state-semi-nonlit-pos-cache-limit',
2544;; both of them are "trimmed" together after a buffer change to ensure
2545;; consistency.
2546;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2547
2529(defvar c-state-semi-nonlit-pos-cache nil) 2548(defvar c-state-semi-nonlit-pos-cache nil)
2530(make-variable-buffer-local 'c-state-semi-nonlit-pos-cache) 2549(make-variable-buffer-local 'c-state-semi-nonlit-pos-cache)
2531;; A list of elements which are either buffer positions (when such positions 2550;; A list of elements which are either buffer positions (when such positions
@@ -2539,12 +2558,62 @@ comment at the start of cc-engine.el for more info."
2539;; is reduced by buffer changes, and increased by invocations of 2558;; is reduced by buffer changes, and increased by invocations of
2540;; `c-parse-ps-state-below'. 2559;; `c-parse-ps-state-below'.
2541 2560
2561(defvar c-state-semi-nonlit-near-cache nil)
2562(make-variable-buffer-local 'c-state-semi-nonlit-near-cache)
2563;; A list of up to six recent results from `c-state-semi-pp-to-literal'. Each
2564;; element is a cons of the buffer position and the `parse-partial-sexp' state
2565;; at that position.
2566
2542(defsubst c-truncate-semi-nonlit-pos-cache (pos) 2567(defsubst c-truncate-semi-nonlit-pos-cache (pos)
2543 ;; Truncate the upper bound of the cache `c-state-semi-nonlit-pos-cache' to 2568 ;; Truncate the upper bound of the cache `c-state-semi-nonlit-pos-cache' to
2544 ;; POS, if it is higher than that position. 2569 ;; POS, if it is higher than that position.
2545 (setq c-state-semi-nonlit-pos-cache-limit 2570 (setq c-state-semi-nonlit-pos-cache-limit
2546 (min c-state-semi-nonlit-pos-cache-limit pos))) 2571 (min c-state-semi-nonlit-pos-cache-limit pos)))
2547 2572
2573(defun c-state-semi-trim-near-cache ()
2574 ;; Remove stale entries in `c-state-semi-nonlit-near-cache', i.e. those
2575 ;; whose positions are above `c-state-semi-nonlit-pos-cache-limit'.
2576 (let ((nc-list c-state-semi-nonlit-near-cache))
2577 (while nc-list
2578 (if (> (caar nc-list) c-state-semi-nonlit-pos-cache-limit)
2579 (setq c-state-semi-nonlit-near-cache
2580 (delq (car nc-list) c-state-semi-nonlit-near-cache)
2581 nc-list c-state-semi-nonlit-near-cache) ; start again in case
2582 ; of list breakage.
2583 (setq nc-list (cdr nc-list))))))
2584
2585(defun c-state-semi-get-near-cache-entry (here)
2586 ;; Return the near cache entry at the highest postion before HERE, if any,
2587 ;; or nil. The near cache entry is of the form (POSITION . STATE), where
2588 ;; STATE has the form of a result of `parse-partial-sexp'.
2589 (let ((nc-pos-state
2590 (or (assq here c-state-semi-nonlit-near-cache)
2591 (let ((nc-list c-state-semi-nonlit-near-cache)
2592 pos (nc-pos 0) cand-pos-state)
2593 (while nc-list
2594 (setq pos (caar nc-list))
2595 (when (and (<= pos here)
2596 (> pos nc-pos))
2597 (setq nc-pos pos
2598 cand-pos-state (car nc-list)))
2599 (setq nc-list (cdr nc-list)))
2600 cand-pos-state))))
2601 (when (and nc-pos-state
2602 (not (eq nc-pos-state (car c-state-semi-nonlit-near-cache))))
2603 ;; Move the found cache entry to the front of the list.
2604 (setq c-state-semi-nonlit-near-cache
2605 (delq nc-pos-state c-state-semi-nonlit-near-cache))
2606 (push nc-pos-state c-state-semi-nonlit-near-cache))
2607 nc-pos-state))
2608
2609(defun c-state-semi-put-near-cache-entry (here state)
2610 ;; Put a new near cache entry into the near cache.
2611 (while (>= (length c-state-semi-nonlit-near-cache) 6)
2612 (setq c-state-semi-nonlit-near-cache
2613 (delq (car (last c-state-semi-nonlit-near-cache))
2614 c-state-semi-nonlit-near-cache)))
2615 (push (cons here state) c-state-semi-nonlit-near-cache))
2616
2548(defun c-state-semi-pp-to-literal (here &optional not-in-delimiter) 2617(defun c-state-semi-pp-to-literal (here &optional not-in-delimiter)
2549 ;; Do a parse-partial-sexp from a position in the buffer before HERE which 2618 ;; Do a parse-partial-sexp from a position in the buffer before HERE which
2550 ;; isn't in a literal, and return information about HERE, either: 2619 ;; isn't in a literal, and return information about HERE, either:
@@ -2564,12 +2633,28 @@ comment at the start of cc-engine.el for more info."
2564 (save-excursion 2633 (save-excursion
2565 (save-restriction 2634 (save-restriction
2566 (widen) 2635 (widen)
2636 (c-state-semi-trim-cache)
2637 (c-state-semi-trim-near-cache)
2638 (setq c-state-semi-nonlit-pos-cache-limit here)
2567 (save-match-data 2639 (save-match-data
2568 (let* ((base-and-state (c-parse-ps-state-below here)) 2640 (let* ((base-and-state (c-state-semi-get-near-cache-entry here))
2569 (base (car base-and-state)) 2641 (base (car base-and-state))
2642 (near-base base)
2570 (s (cdr base-and-state)) 2643 (s (cdr base-and-state))
2571 (s (parse-partial-sexp base here nil nil s)) 2644 far-base-and-state far-base far-s ty)
2572 ty) 2645 (if (or (not base)
2646 (< base (- here 100)))
2647 (progn
2648 (setq far-base-and-state (c-parse-ps-state-below here)
2649 far-base (car far-base-and-state)
2650 far-s (cdr far-base-and-state))
2651 (when (or (not base) (> far-base base))
2652 (setq base far-base
2653 s far-s))))
2654 (when (> here base)
2655 (setq s (parse-partial-sexp base here nil nil s)))
2656 (when (not (eq near-base here))
2657 (c-state-semi-put-near-cache-entry here s))
2573 (cond 2658 (cond
2574 ((or (nth 3 s) 2659 ((or (nth 3 s)
2575 (and (nth 4 s) 2660 (and (nth 4 s)
@@ -2612,12 +2697,28 @@ comment at the start of cc-engine.el for more info."
2612 (save-excursion 2697 (save-excursion
2613 (save-restriction 2698 (save-restriction
2614 (widen) 2699 (widen)
2700 (c-state-semi-trim-cache)
2701 (c-state-semi-trim-near-cache)
2702 (setq c-state-semi-nonlit-pos-cache-limit here)
2615 (save-match-data 2703 (save-match-data
2616 (let* ((base-and-state (c-parse-ps-state-below here)) 2704 (let* ((base-and-state (c-state-semi-get-near-cache-entry here))
2617 (base (car base-and-state)) 2705 (base (car base-and-state))
2706 (near-base base)
2618 (s (cdr base-and-state)) 2707 (s (cdr base-and-state))
2619 (s (parse-partial-sexp base here nil nil s)) 2708 far-base-and-state far-base far-s ty start)
2620 ty start) 2709 (if (or (not base)
2710 (< base (- here 100)))
2711 (progn
2712 (setq far-base-and-state (c-parse-ps-state-below here)
2713 far-base (car far-base-and-state)
2714 far-s (cdr far-base-and-state))
2715 (when (or (not base) (> far-base base))
2716 (setq base far-base
2717 s far-s))))
2718 (when (> here base)
2719 (setq s (parse-partial-sexp base here nil nil s)))
2720 (when (not (eq near-base here))
2721 (c-state-semi-put-near-cache-entry here s))
2621 (cond 2722 (cond
2622 ((or (nth 3 s) 2723 ((or (nth 3 s)
2623 (and (nth 4 s) 2724 (and (nth 4 s)
@@ -2812,6 +2913,14 @@ comment at the start of cc-engine.el for more info."
2812 elt 2913 elt
2813 (car elt))) 2914 (car elt)))
2814 2915
2916(defun c-state-semi-trim-cache ()
2917 ;; Trim the `c-state-semi-nonlit-pos-cache' to take account of buffer
2918 ;; changes, indicated by `c-state-semi-nonlit-pos-cache-limit'.
2919 (while (and c-state-semi-nonlit-pos-cache
2920 (> (c-ps-state-cache-pos (car c-state-semi-nonlit-pos-cache))
2921 c-state-semi-nonlit-pos-cache-limit))
2922 (setq c-state-semi-nonlit-pos-cache (cdr c-state-semi-nonlit-pos-cache))))
2923
2815(defun c-parse-ps-state-below (here) 2924(defun c-parse-ps-state-below (here)
2816 ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where 2925 ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where
2817 ;; CACHE-POS is a position not very far before HERE for which the 2926 ;; CACHE-POS is a position not very far before HERE for which the
@@ -2822,14 +2931,9 @@ comment at the start of cc-engine.el for more info."
2822 (save-excursion 2931 (save-excursion
2823 (save-restriction 2932 (save-restriction
2824 (widen) 2933 (widen)
2934 (c-state-semi-trim-cache)
2825 (let ((c c-state-semi-nonlit-pos-cache) 2935 (let ((c c-state-semi-nonlit-pos-cache)
2826 elt state npos high-elt) 2936 elt state npos high-elt)
2827 ;; Trim the cache to take account of buffer changes.
2828 (while (and c (> (c-ps-state-cache-pos (car c))
2829 c-state-semi-nonlit-pos-cache-limit))
2830 (setq c (cdr c)))
2831 (setq c-state-semi-nonlit-pos-cache c)
2832
2833 (while (and c (> (c-ps-state-cache-pos (car c)) here)) 2937 (while (and c (> (c-ps-state-cache-pos (car c)) here))
2834 (setq high-elt (car c)) 2938 (setq high-elt (car c))
2835 (setq c (cdr c))) 2939 (setq c (cdr c)))
@@ -5617,7 +5721,7 @@ comment at the start of cc-engine.el for more info."
5617 (when (not high-elt) 5721 (when (not high-elt)
5618 (setq stack (cdr elt)) 5722 (setq stack (cdr elt))
5619 (while 5723 (while
5620 ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. 5724 ;; Add an element to `c-bs-cache' each iteration.
5621 (<= (setq npos (+ pos c-bs-interval)) here) 5725 (<= (setq npos (+ pos c-bs-interval)) here)
5622 (setq elt (c-update-brace-stack stack pos npos)) 5726 (setq elt (c-update-brace-stack stack pos npos))
5623 (setq npos (car elt)) 5727 (setq npos (car elt))
@@ -6469,44 +6573,52 @@ comment at the start of cc-engine.el for more info."
6469 ;; 6573 ;;
6470 ;; FIXME!!! This routine ignores the possibility of macros entirely. 6574 ;; FIXME!!! This routine ignores the possibility of macros entirely.
6471 ;; 2010-01-29. 6575 ;; 2010-01-29.
6472 (save-excursion 6576 (when (and (> end beg)
6473 (c-save-buffer-state 6577 (or
6474 ((beg-lit-start (progn (goto-char beg) (c-literal-start))) 6578 (progn
6475 (end-lit-limits (progn (goto-char end) (c-literal-limits))) 6579 (goto-char beg)
6476 new-beg new-end beg-limit end-limit) 6580 (search-backward "<" (max (- (point) 1024) (point-min)) t))
6477 ;; Locate the earliest < after the barrier before the changed region, 6581 (progn
6478 ;; which isn't already marked as a paren. 6582 (goto-char end)
6479 (goto-char (or beg-lit-start beg)) 6583 (search-forward ">" (min (+ (point) 1024) (point-max)) t))))
6480 (setq beg-limit (c-determine-limit 512)) 6584 (save-excursion
6481 6585 (c-save-buffer-state
6482 ;; Remove the syntax-table/category properties from each pertinent <...> 6586 ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
6483 ;; pair. Firstly, the ones with the < before beg and > after beg.... 6587 (end-lit-limits (progn (goto-char end) (c-literal-limits)))
6484 (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit) 6588 new-beg new-end beg-limit end-limit)
6485 (eq (char-before) ?<)) 6589 ;; Locate the earliest < after the barrier before the changed region,
6486 (c-backward-token-2) 6590 ;; which isn't already marked as a paren.
6487 (when (eq (char-after) ?<) 6591 (goto-char (or beg-lit-start beg))
6488 (c-clear-<-pair-props-if-match-after beg) 6592 (setq beg-limit (c-determine-limit 512))
6489 (setq new-beg (point)))) 6593
6490 (c-forward-syntactic-ws) 6594 ;; Remove the syntax-table/category properties from each pertinent <...>
6595 ;; pair. Firstly, the ones with the < before beg and > after beg....
6596 (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit)
6597 (eq (char-before) ?<))
6598 (c-backward-token-2)
6599 (when (eq (char-after) ?<)
6600 (c-clear-<-pair-props-if-match-after beg)
6601 (setq new-beg (point))))
6602 (c-forward-syntactic-ws)
6491 6603
6492 ;; ...Then the ones with < before end and > after end. 6604 ;; ...Then the ones with < before end and > after end.
6493 (goto-char (if end-lit-limits (cdr end-lit-limits) end)) 6605 (goto-char (if end-lit-limits (cdr end-lit-limits) end))
6494 (setq end-limit (c-determine-+ve-limit 512)) 6606 (setq end-limit (c-determine-+ve-limit 512))
6495 (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end) 6607 (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end)
6496 (eq (char-before) ?>)) 6608 (eq (char-before) ?>))
6497 (c-end-of-current-token) 6609 (c-end-of-current-token)
6498 (when (eq (char-before) ?>) 6610 (when (eq (char-before) ?>)
6499 (c-clear->-pair-props-if-match-before end (1- (point))) 6611 (c-clear->-pair-props-if-match-before end (1- (point)))
6500 (setq new-end (point)))) 6612 (setq new-end (point))))
6501 (c-backward-syntactic-ws) 6613 (c-backward-syntactic-ws)
6502 6614
6503 ;; Extend the fontification region, if needed. 6615 ;; Extend the fontification region, if needed.
6504 (and new-beg 6616 (and new-beg
6505 (< new-beg c-new-BEG) 6617 (< new-beg c-new-BEG)
6506 (setq c-new-BEG new-beg)) 6618 (setq c-new-BEG new-beg))
6507 (and new-end 6619 (and new-end
6508 (> new-end c-new-END) 6620 (> new-end c-new-END)
6509 (setq c-new-END new-end))))) 6621 (setq c-new-END new-end))))))
6510 6622
6511(defun c-after-change-check-<>-operators (beg end) 6623(defun c-after-change-check-<>-operators (beg end)
6512 ;; This is called from `after-change-functions' when 6624 ;; This is called from `after-change-functions' when
@@ -7123,7 +7235,8 @@ comment at the start of cc-engine.el for more info."
7123 t) 7235 t)
7124 ((save-excursion 7236 ((save-excursion
7125 (and 7237 (and
7126 (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\=" nil t) 7238 (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\="
7239 (c-point 'bol) t)
7127 (setq id (match-string-no-properties 1)) 7240 (setq id (match-string-no-properties 1))
7128 (let* ((quoted-id (regexp-quote id)) 7241 (let* ((quoted-id (regexp-quote id))
7129 (quoted-id-depth (regexp-opt-depth quoted-id))) 7242 (quoted-id-depth (regexp-opt-depth quoted-id)))
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index ea865e0b0fb..bd62fc754ab 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1825,28 +1825,30 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1825 ;; by `c-doc-line-join-re'), return the position of the first line of the 1825 ;; by `c-doc-line-join-re'), return the position of the first line of the
1826 ;; sequence. Otherwise, return nil. Point has no significance at entry to 1826 ;; sequence. Otherwise, return nil. Point has no significance at entry to
1827 ;; and exit from this function. 1827 ;; and exit from this function.
1828 (goto-char pos) 1828 (when (not (equal c-doc-line-join-re "a\\`"))
1829 (back-to-indentation) 1829 (goto-char pos)
1830 (and (or (looking-at c-comment-start-regexp) 1830 (back-to-indentation)
1831 (memq (c-literal-type (c-literal-limits)) '(c c++))) 1831 (and (or (looking-at c-comment-start-regexp)
1832 (progn 1832 (memq (c-literal-type (c-literal-limits)) '(c c++)))
1833 (end-of-line) 1833 (progn
1834 (let ((here (point))) 1834 (end-of-line)
1835 (while (re-search-backward c-doc-line-join-re (c-point 'bopl) t)) 1835 (let ((here (point)))
1836 (and (not (eq (point) here)) 1836 (while (re-search-backward c-doc-line-join-re (c-point 'bopl) t))
1837 (c-point 'bol)))))) 1837 (and (not (eq (point) here))
1838 (c-point 'bol)))))))
1838 1839
1839(defun c-doc-fl-decl-end (pos) 1840(defun c-doc-fl-decl-end (pos)
1840 ;; If the line containing POS is continued by a doc comment continuation 1841 ;; If the line containing POS is continued by a doc comment continuation
1841 ;; marker (as defined by `c-doc-line-join-re), return the position of 1842 ;; marker (as defined by `c-doc-line-join-re), return the position of
1842 ;; the BOL at the end of the sequence. Otherwise, return nil. Point has no 1843 ;; the BOL at the end of the sequence. Otherwise, return nil. Point has no
1843 ;; significance at entry to and exit from this function. 1844 ;; significance at entry to and exit from this function.
1844 (goto-char pos) 1845 (when (not (equal c-doc-line-join-re "a\\`"))
1845 (back-to-indentation) 1846 (goto-char pos)
1846 (let ((here (point))) 1847 (back-to-indentation)
1847 (while (re-search-forward c-doc-line-join-re (c-point 'eonl) t)) 1848 (let ((here (point)))
1848 (and (not (eq (point) here)) 1849 (while (re-search-forward c-doc-line-join-re (c-point 'eonl) t))
1849 (c-point 'bonl)))) 1850 (and (not (eq (point) here))
1851 (c-point 'bonl)))))
1850 1852
1851(defun c-fl-decl-start (pos) 1853(defun c-fl-decl-start (pos)
1852 ;; If the beginning of the line containing POS is in the middle of a "local" 1854 ;; If the beginning of the line containing POS is in the middle of a "local"
@@ -1874,13 +1876,10 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1874 ;; In C++ Mode, first check if we are within a (possibly nested) lambda 1876 ;; In C++ Mode, first check if we are within a (possibly nested) lambda
1875 ;; form capture list. 1877 ;; form capture list.
1876 (when (c-major-mode-is 'c++-mode) 1878 (when (c-major-mode-is 'c++-mode)
1877 (let ((paren-state (c-parse-state)) 1879 (save-excursion
1878 opener) 1880 (while (and (c-go-up-list-backward nil bod-lim)
1879 (save-excursion 1881 (c-looking-at-c++-lambda-capture-list))
1880 (while (setq opener (c-pull-open-brace paren-state)) 1882 (setq capture-opener (point)))))
1881 (goto-char opener)
1882 (if (c-looking-at-c++-lambda-capture-list)
1883 (setq capture-opener (point)))))))
1884 1883
1885 (while 1884 (while
1886 ;; Go to a less nested declaration each time round this loop. 1885 ;; Go to a less nested declaration each time round this loop.