aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2024-10-15 21:08:41 +0000
committerAlan Mackenzie2024-10-15 21:14:34 +0000
commitfdac10b216f7b47e2eea129d2a96807a0c2055f3 (patch)
tree844390fadf05edbbc9ce2e39d19c73e941924b29
parent1686d48417315f809403aeb29559788ef4b755a6 (diff)
downloademacs-fdac10b216f7b47e2eea129d2a96807a0c2055f3.tar.gz
emacs-fdac10b216f7b47e2eea129d2a96807a0c2055f3.zip
CC Mode: Rationalize and optimize cache invalidation (2).
Replace separate syntax-table text property changes and cache invalidation with macros which do both together. Correct a bug in the invocation of XEmacs's map-extents. * lisp/progmodes/cc-defs.el (c-put-syntax-table-trim-caches) (c-clear-syntax-table-trim-caches) (c-clear-syntax-table-properties-trim-caches) (c-clear-syntax-table-with-value-trim-caches) (c-clear-syntax-table-with-value-on-char-trim-caches) (c-put-syntax-table-properties-on-char-trim-caches): New macros. (c-clear-char-properties, c-clear-char-property-with-value) (c-clear-char-property-with-value-on-char): Correct the invocation of XEmacs's map-extents by returning nil from the mapping function to prevent premature exit from map-extents. (c-clear-char-property-with-value-function) (c-clear-char-property-with-value) (c-clear-char-property-with-value-on-char-function) (c-clear-char-property-with-value-on-char) (c-put-char-properties-on-char): Enhance to return the position of the first changed char property (or nil). * lisp/progmodes/cc-awk.el (c-awk-set-string-regexp-syntax-table-properties) (c-awk-set-syntax-table-properties) * lisp/progmodes/cc-engine.el (c-depropertize-ml-string-delims) (c-after-change-unmark-ml-strings, c-propertize-ml-string-id) (c-propertize-ml-string-opener, c-depropertize-ml-string) (c-depropertize-ml-strings-in-region) * lisp/progmodes/cc-mode.el (c-depropertize-CPP) (c-neutralize-CPP-line, c-put-syn-tab, c-clear-syn-tab) (c-parse-quotes-before-change, c-parse-quotes-after-change) (c-before-change-fix-comment-escapes) (c-after-change-fix-comment-escapes): Use the new macros from cc-defs.el. * lisp/progmodes/cc-mode.el (c-trim-cache-first-punctuation-prop): Remove. (c-depropertize-CPP): Remove calls to the above function.
-rw-r--r--lisp/progmodes/cc-awk.el10
-rw-r--r--lisp/progmodes/cc-defs.el123
-rw-r--r--lisp/progmodes/cc-engine.el164
-rw-r--r--lisp/progmodes/cc-mode.el76
4 files changed, 234 insertions, 139 deletions
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index e377c4831fc..b71442c4751 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -761,14 +761,14 @@
761 (c-put-string-fence end)) 761 (c-put-string-fence end))
762 ((eq (char-after beg) ?/) ; Properly bracketed regexp 762 ((eq (char-after beg) ?/) ; Properly bracketed regexp
763 (c-put-char-property beg 'syntax-table '(7)) ; (7) = "string" 763 (c-put-char-property beg 'syntax-table '(7)) ; (7) = "string"
764 (c-put-char-property end 'syntax-table '(7))) 764 (c-put-syntax-table-trim-caches end '(7)))
765 (t)) ; Properly bracketed string: Nothing to do. 765 (t)) ; Properly bracketed string: Nothing to do.
766 ;; Now change the properties of any escaped "s in the string to punctuation. 766 ;; Now change the properties of any escaped "s in the string to punctuation.
767 (save-excursion 767 (save-excursion
768 (goto-char (1+ beg)) 768 (goto-char (1+ beg))
769 (or (eobp) 769 (or (eobp)
770 (while (search-forward "\"" end t) 770 (while (search-forward "\"" end t)
771 (c-put-char-property (1- (point)) 'syntax-table '(1)))))) 771 (c-put-syntax-table-trim-caches (1- (point)) '(1))))))
772 772
773(defun c-awk-syntax-tablify-string () 773(defun c-awk-syntax-tablify-string ()
774 ;; Point is at the opening " or _" of a string. Set the syntax-table 774 ;; Point is at the opening " or _" of a string. Set the syntax-table
@@ -861,7 +861,7 @@
861 (let (anchor 861 (let (anchor
862 (anchor-state-/div nil)) ; t means a following / would be a div sign. 862 (anchor-state-/div nil)) ; t means a following / would be a div sign.
863 (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant. 863 (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant.
864 (c-clear-char-properties (point) lim 'syntax-table) 864 (c-clear-syntax-table-properties-trim-caches (point) lim)
865 ;; Once round the next loop for each string, regexp, or div sign 865 ;; Once round the next loop for each string, regexp, or div sign
866 (while (progn 866 (while (progn
867 ;; Skip any "harmless" lines before the next tricky one. 867 ;; Skip any "harmless" lines before the next tricky one.
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index e45ab76ec07..b6137c02ca9 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1248,6 +1248,14 @@ MODE is either a mode symbol or a list of mode symbols."
1248 `((setq c-syntax-table-hwm (min c-syntax-table-hwm -pos-)))) 1248 `((setq c-syntax-table-hwm (min c-syntax-table-hwm -pos-))))
1249 (put-text-property -pos- (1+ -pos-) ',property ,value)))) 1249 (put-text-property -pos- (1+ -pos-) ',property ,value))))
1250 1250
1251(defmacro c-put-syntax-table-trim-caches (pos value)
1252 ;; Put a 'syntax-table property with VALUE at POS. Also invalidate four
1253 ;; caches from the position POS.
1254 (declare (debug t))
1255 `(let ((-pos- ,pos))
1256 (c-put-char-property -pos- 'syntax-table ,value)
1257 (c-truncate-lit-pos/state-cache -pos-)))
1258
1251(defmacro c-put-string-fence (pos) 1259(defmacro c-put-string-fence (pos)
1252 ;; Put the string-fence syntax-table text property at POS. 1260 ;; Put the string-fence syntax-table text property at POS.
1253 ;; Since the character there cannot then count as syntactic whitespace, 1261 ;; Since the character there cannot then count as syntactic whitespace,
@@ -1333,6 +1341,14 @@ MODE is either a mode symbol or a list of mode symbols."
1333 ;; Emacs < 21. 1341 ;; Emacs < 21.
1334 `(c-clear-char-property-fun ,pos ',property)))) 1342 `(c-clear-char-property-fun ,pos ',property))))
1335 1343
1344(defmacro c-clear-syntax-table-trim-caches (pos)
1345 ;; Remove the 'syntax-table property at POS and invalidate the four caches
1346 ;; from that position.
1347 (declare (debug t))
1348 `(let ((-pos- ,pos))
1349 (c-clear-char-property -pos- 'syntax-table)
1350 (c-truncate-lit-pos/state-cache -pos-)))
1351
1336(defmacro c-min-property-position (from to property) 1352(defmacro c-min-property-position (from to property)
1337 ;; Return the first position in the range [FROM to) where the text property 1353 ;; Return the first position in the range [FROM to) where the text property
1338 ;; PROPERTY is set, or `most-positive-fixnum' if there is no such position. 1354 ;; PROPERTY is set, or `most-positive-fixnum' if there is no such position.
@@ -1387,7 +1403,8 @@ MODE is either a mode symbol or a list of mode symbols."
1387 (c-use-extents 1403 (c-use-extents
1388 ;; XEmacs 1404 ;; XEmacs
1389 `(map-extents (lambda (ext ignored) 1405 `(map-extents (lambda (ext ignored)
1390 (delete-extent ext)) 1406 (delete-extent ext)
1407 nil) ; To prevent exit from `map-extents'.
1391 nil ret -to- nil nil ',property)) 1408 nil ret -to- nil nil ',property))
1392 ((and (fboundp 'syntax-ppss) 1409 ((and (fboundp 'syntax-ppss)
1393 (eq property 'syntax-table)) 1410 (eq property 'syntax-table))
@@ -1402,6 +1419,15 @@ MODE is either a mode symbol or a list of mode symbols."
1402 ret) 1419 ret)
1403 nil))) 1420 nil)))
1404 1421
1422(defmacro c-clear-syntax-table-properties-trim-caches (from to)
1423 ;; Remove all occurrences of the 'syntax-table property in (FROM TO) and
1424 ;; invalidate the four caches from the first position from which the
1425 ;; property was removed, if any.
1426 (declare (debug t))
1427 `(let ((first (c-clear-char-properties ,from ,to 'syntax-table)))
1428 (when first
1429 (c-truncate-lit-pos/state-cache first))))
1430
1405(defmacro c-clear-syn-tab-properties (from to) 1431(defmacro c-clear-syn-tab-properties (from to)
1406 ;; Remove all occurrences of the `syntax-table' and `c-fl-syn-tab' text 1432 ;; Remove all occurrences of the `syntax-table' and `c-fl-syn-tab' text
1407 ;; properties between FROM and TO. 1433 ;; properties between FROM and TO.
@@ -1492,8 +1518,10 @@ point is then left undefined."
1492 "Remove all text-properties PROPERTY from the region (FROM, TO) 1518 "Remove all text-properties PROPERTY from the region (FROM, TO)
1493which have the value VALUE, as tested by `equal'. These 1519which have the value VALUE, as tested by `equal'. These
1494properties are assumed to be over individual characters, having 1520properties are assumed to be over individual characters, having
1495been put there by `c-put-char-property'. POINT remains unchanged." 1521been put there by `c-put-char-property'. POINT remains unchanged.
1496 (let ((place from) end-place) 1522Return the position of the first removed property, if any, or nil."
1523 (let ((place from) end-place
1524 first)
1497 (while ; loop round occurrences of (PROPERTY VALUE) 1525 (while ; loop round occurrences of (PROPERTY VALUE)
1498 (progn 1526 (progn
1499 (while ; loop round changes in PROPERTY till we find VALUE 1527 (while ; loop round changes in PROPERTY till we find VALUE
@@ -1506,25 +1534,51 @@ been put there by `c-put-char-property'. POINT remains unchanged."
1506 (setq c-syntax-table-hwm (min c-syntax-table-hwm place))) 1534 (setq c-syntax-table-hwm (min c-syntax-table-hwm place)))
1507 (setq end-place (c-next-single-property-change place property nil to)) 1535 (setq end-place (c-next-single-property-change place property nil to))
1508 (remove-text-properties place end-place (list property nil)) 1536 (remove-text-properties place end-place (list property nil))
1537 (unless first (setq first place))
1509 ;; Do we have to do anything with stickiness here? 1538 ;; Do we have to do anything with stickiness here?
1510 (setq place end-place)))) 1539 (setq place end-place))
1540 first))
1511 1541
1512(defmacro c-clear-char-property-with-value (from to property value) 1542(defmacro c-clear-char-property-with-value (from to property value)
1513 "Remove all text-properties PROPERTY from the region [FROM, TO) 1543 "Remove all text-properties PROPERTY from the region [FROM, TO)
1514which have the value VALUE, as tested by `equal'. These 1544which have the value VALUE, as tested by `equal'. These
1515properties are assumed to be over individual characters, having 1545properties are assumed to be over individual characters, having
1516been put there by `c-put-char-property'. POINT remains unchanged." 1546been put there by `c-put-char-property'. POINT remains unchanged.
1547Return the position of the first removed property, or nil."
1517 (declare (debug t)) 1548 (declare (debug t))
1518 (if c-use-extents 1549 (if c-use-extents
1519 ;; XEmacs 1550 ;; XEmacs
1520 `(let ((-property- ,property)) 1551 `(let ((-property- ,property)
1552 (first (1+ (point-max))))
1521 (map-extents (lambda (ext val) 1553 (map-extents (lambda (ext val)
1522 (if (equal (extent-property ext -property-) val) 1554 ;; In the following, the test on the extent's property
1523 (delete-extent ext))) 1555 ;; is probably redundant. See documentation of
1524 nil ,from ,to ,value nil -property-)) 1556 ;; `map-extents'. NO it's NOT! This automatic check
1525 ;; GNU Emacs 1557 ;; would require another argument to `map-extents',
1558 ;; but the test would use `eq', not `equal', so it's
1559 ;; no good. :-(
1560 (when (equal (extent-property ext -property-) val)
1561 (setq first (min first
1562 (extent-start-position ext)))
1563 (delete-extent ext))
1564 nil)
1565 nil ,from ,to ,value nil -property-)
1566 (and (<= first (point-max)) first))
1567 ;; Gnu Emacs
1526 `(c-clear-char-property-with-value-function ,from ,to ,property ,value))) 1568 `(c-clear-char-property-with-value-function ,from ,to ,property ,value)))
1527 1569
1570(defmacro c-clear-syntax-table-with-value-trim-caches (from to value)
1571 "Remove all `syntax-table' text-properties with value VALUE from [FROM, TO)
1572and invalidate the four caches from the first postion, if any, where a
1573property was removed. Return the position of the first property removed,
1574if any, else nil. POINT and the match data remain unchanged."
1575 (declare (debug t))
1576 `(let ((first
1577 (c-clear-char-property-with-value ,from ,to 'syntax-table ,value)))
1578 (when first
1579 (c-truncate-lit-pos/state-cache first))
1580 first))
1581
1528(defmacro c-search-forward-char-property-with-value-on-char 1582(defmacro c-search-forward-char-property-with-value-on-char
1529 (property value char &optional limit) 1583 (property value char &optional limit)
1530 "Search forward for a text-property PROPERTY having value VALUE on a 1584 "Search forward for a text-property PROPERTY having value VALUE on a
@@ -1620,7 +1674,8 @@ property, or nil."
1620 (or first 1674 (or first
1621 (progn (setq first place) 1675 (progn (setq first place)
1622 (when (eq property 'syntax-table) 1676 (when (eq property 'syntax-table)
1623 (setq c-syntax-table-hwm (min c-syntax-table-hwm place)))))) 1677 (setq c-syntax-table-hwm
1678 (min c-syntax-table-hwm place))))))
1624 ;; Do we have to do anything with stickiness here? 1679 ;; Do we have to do anything with stickiness here?
1625 (setq place (1+ place))) 1680 (setq place (1+ place)))
1626 first)) 1681 first))
@@ -1639,26 +1694,46 @@ property, or nil."
1639 (-char- ,char) 1694 (-char- ,char)
1640 (first (1+ (point-max)))) 1695 (first (1+ (point-max))))
1641 (map-extents (lambda (ext val) 1696 (map-extents (lambda (ext val)
1642 (when (and (equal (extent-property ext -property-) val) 1697 ;; In the following, the test on the extent's property
1698 ;; is probably redundant. See documentation of
1699 ;; map-extents. NO! See
1700 ;; `c-clear-char-property-with-value'.
1701 (when (and (equal (extent-property ext -property-)
1702 val)
1643 (eq (char-after 1703 (eq (char-after
1644 (extent-start-position ext)) 1704 (extent-start-position ext))
1645 -char-)) 1705 -char-))
1646 (setq first (min first (extent-start-position ext))) 1706 (setq first (min first (extent-start-position ext)))
1647 (delete-extent ext))) 1707 (delete-extent ext))
1708 nil)
1648 nil ,from ,to ,value nil -property-) 1709 nil ,from ,to ,value nil -property-)
1649 (and (<= first (point-max)) first)) 1710 (and (<= first (point-max)) first))
1650 ;; GNU Emacs 1711 ;; Gnu Emacs
1651 `(c-clear-char-property-with-value-on-char-function ,from ,to ,property 1712 `(c-clear-char-property-with-value-on-char-function ,from ,to ,property
1652 ,value ,char))) 1713 ,value ,char)))
1653 1714
1715(defmacro c-clear-syntax-table-with-value-on-char-trim-caches
1716 (from to value char)
1717 "Remove all `syntax-table' properties with VALUE on CHAR in [FROM, TO),
1718as tested by `equal', and invalidate the four caches from the first position,
1719if any, where a property was removed. POINT and the match data remain
1720unchanged."
1721 (declare (debug t))
1722 `(let ((first (c-clear-char-property-with-value-on-char
1723 ,from ,to 'syntax-table ,value ,char)))
1724 (when first
1725 (c-truncate-lit-pos/state-cache first))))
1726
1654(defmacro c-put-char-properties-on-char (from to property value char) 1727(defmacro c-put-char-properties-on-char (from to property value char)
1655 ;; This needs to be a macro because `property' passed to 1728 ;; This needs to be a macro because `property' passed to
1656 ;; `c-put-char-property' must be a constant. 1729 ;; `c-put-char-property' must be a constant.
1657 "Put the text property PROPERTY with value VALUE on characters 1730 "Put the text property PROPERTY with value VALUE on characters
1658with value CHAR in the region [FROM to)." 1731with value CHAR in the region [FROM to). Return the position of the
1732first char changed, if any, else nil."
1659 (declare (debug t)) 1733 (declare (debug t))
1660 `(let ((skip-string (concat "^" (list ,char))) 1734 `(let ((skip-string (concat "^" (list ,char)))
1661 (-to- ,to)) 1735 (-to- ,to)
1736 first)
1662 (save-excursion 1737 (save-excursion
1663 (goto-char ,from) 1738 (goto-char ,from)
1664 (while (progn (skip-chars-forward skip-string -to-) 1739 (while (progn (skip-chars-forward skip-string -to-)
@@ -1667,8 +1742,20 @@ with value CHAR in the region [FROM to)."
1667 (eq (eval property) 'syntax-table)) 1742 (eq (eval property) 'syntax-table))
1668 `((setq c-syntax-table-hwm (min c-syntax-table-hwm (point))))) 1743 `((setq c-syntax-table-hwm (min c-syntax-table-hwm (point)))))
1669 (c-put-char-property (point) ,property ,value) 1744 (c-put-char-property (point) ,property ,value)
1670 (forward-char))))) 1745 (when (not first) (setq first (point)))
1671 1746 (forward-char)))
1747 first))
1748
1749(defmacro c-put-syntax-table-properties-on-char-trim-caches
1750 (from to value char)
1751 "Put a `syntax-table' text property with value VALUE on all characters
1752with value CHAR in the region [FROM to), and invalidate the four caches
1753from the first position, if any, where a property was put."
1754 (declare (debug t))
1755 `(let ((first (c-put-char-properties-on-char
1756 ,from ,to 'syntax-table ,value ,char)))
1757 (when first
1758 (c-truncate-lit-pos/state-cache first))))
1672 1759
1673;; Miscellaneous macro(s) 1760;; Miscellaneous macro(s)
1674(defvar c-string-fences-set-flag nil) 1761(defvar c-string-fences-set-flag nil)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 868267f06f4..8fd2b2dc49c 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -164,6 +164,7 @@
164(cc-require-when-compile 'cc-langs) 164(cc-require-when-compile 'cc-langs)
165(cc-require 'cc-vars) 165(cc-require 'cc-vars)
166 166
167(defvar c-state-cache-invalid-pos)
167(defvar c-doc-line-join-re) 168(defvar c-doc-line-join-re)
168(defvar c-doc-bright-comment-start-re) 169(defvar c-doc-bright-comment-start-re)
169(defvar c-doc-line-join-end-ch) 170(defvar c-doc-line-join-end-ch)
@@ -3210,6 +3211,7 @@ comment at the start of cc-engine.el for more info."
3210 (c-full-put-near-cache-entry here s nil)) 3211 (c-full-put-near-cache-entry here s nil))
3211 (list s)))))))) 3212 (list s))))))))
3212 3213
3214
3213(defsubst c-truncate-lit-pos-cache (pos) 3215(defsubst c-truncate-lit-pos-cache (pos)
3214 ;; Truncate the upper bound of each of the three caches to POS, if it is 3216 ;; Truncate the upper bound of each of the three caches to POS, if it is
3215 ;; higher than that position. 3217 ;; higher than that position.
@@ -3217,6 +3219,12 @@ comment at the start of cc-engine.el for more info."
3217 c-semi-near-cache-limit (min c-semi-near-cache-limit pos) 3219 c-semi-near-cache-limit (min c-semi-near-cache-limit pos)
3218 c-full-near-cache-limit (min c-full-near-cache-limit pos))) 3220 c-full-near-cache-limit (min c-full-near-cache-limit pos)))
3219 3221
3222(defsubst c-truncate-lit-pos/state-cache (pos)
3223 ;; Truncate the upper bound of each of the four caches to POS, if it is
3224 ;; higher than that position.
3225 (c-truncate-lit-pos-cache pos)
3226 (setq c-state-cache-invalid-pos (min c-state-cache-invalid-pos pos)))
3227
3220(defun c-foreign-truncate-lit-pos-cache (beg _end) 3228(defun c-foreign-truncate-lit-pos-cache (beg _end)
3221 "Truncate CC Mode's literal cache. 3229 "Truncate CC Mode's literal cache.
3222 3230
@@ -3266,7 +3274,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
3266;; subparen that is closed before the last recorded position. 3274;; subparen that is closed before the last recorded position.
3267;; 3275;;
3268;; The exact position is chosen to try to be close to yet earlier than 3276;; The exact position is chosen to try to be close to yet earlier than
3269;; the position where `c-state-cache' will be called next. Right now 3277;; the position where `c-parse-state' will be called next. Right now
3270;; the heuristic is to set it to the position after the last found 3278;; the heuristic is to set it to the position after the last found
3271;; closing paren (of any type) before the line on which 3279;; closing paren (of any type) before the line on which
3272;; `c-parse-state' was called. That is chosen primarily to work well 3280;; `c-parse-state' was called. That is chosen primarily to work well
@@ -3282,6 +3290,19 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
3282;; the middle of the desert, as long as it is not within a brace pair 3290;; the middle of the desert, as long as it is not within a brace pair
3283;; recorded in `c-state-cache' or a paren/bracket pair. 3291;; recorded in `c-state-cache' or a paren/bracket pair.
3284 3292
3293(defvar c-state-cache-invalid-pos 1)
3294(make-variable-buffer-local 'c-state-cache-invalid-pos)
3295;; This variable is always a number, and is typically eq to
3296;; `c-state-cache-good-pos'.
3297;;
3298;; Its purpose is to record the position that `c-invalidate-state-cache' needs
3299;; to trim `c-state-cache' to.
3300;;
3301;; When a `syntax-table' text property has been
3302;; modified at a position before `c-state-cache-good-pos', it gets set to
3303;; the lowest such position. When that variable is nil,
3304;; `c-state-cache-invalid-pos' is set to `c-state-point-min-literal'.
3305
3285;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3306;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3286;; We maintain a simple cache of positions which aren't in a literal, so as to 3307;; We maintain a simple cache of positions which aren't in a literal, so as to
3287;; speed up testing for non-literality. 3308;; speed up testing for non-literality.
@@ -3747,6 +3768,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
3747 (c-state-mark-point-min-literal) 3768 (c-state-mark-point-min-literal)
3748 (setq c-state-cache nil 3769 (setq c-state-cache nil
3749 c-state-cache-good-pos c-state-min-scan-pos 3770 c-state-cache-good-pos c-state-min-scan-pos
3771 c-state-cache-invalid-pos c-state-cache-good-pos
3750 c-state-brace-pair-desert nil)) 3772 c-state-brace-pair-desert nil))
3751 3773
3752 ;; point-min has MOVED FORWARD. 3774 ;; point-min has MOVED FORWARD.
@@ -3770,7 +3792,8 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
3770 ; inside a recorded 3792 ; inside a recorded
3771 ; brace pair. 3793 ; brace pair.
3772 (setq c-state-cache nil 3794 (setq c-state-cache nil
3773 c-state-cache-good-pos c-state-min-scan-pos) 3795 c-state-cache-good-pos c-state-min-scan-pos
3796 c-state-cache-invalid-pos c-state-cache-good-pos)
3774 ;; Do not alter the original `c-state-cache' structure, since there 3797 ;; Do not alter the original `c-state-cache' structure, since there
3775 ;; may be a loop suspended which is looping through that structure. 3798 ;; may be a loop suspended which is looping through that structure.
3776 ;; This may have been the cause of bug #37910. 3799 ;; This may have been the cause of bug #37910.
@@ -3778,7 +3801,8 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
3778 (setcdr ptr nil) 3801 (setcdr ptr nil)
3779 (setq c-state-cache (copy-sequence c-state-cache)) 3802 (setq c-state-cache (copy-sequence c-state-cache))
3780 (setcdr ptr cdr-ptr)) 3803 (setcdr ptr cdr-ptr))
3781 (setq c-state-cache-good-pos (1+ (c-state-cache-top-lparen)))) 3804 (setq c-state-cache-good-pos (1+ (c-state-cache-top-lparen))
3805 c-state-cache-invalid-pos c-state-cache-good-pos))
3782 ))) 3806 )))
3783 3807
3784 (setq c-state-point-min (point-min))) 3808 (setq c-state-point-min (point-min)))
@@ -4302,6 +4326,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4302(defun c-state-cache-init () 4326(defun c-state-cache-init ()
4303 (setq c-state-cache nil 4327 (setq c-state-cache nil
4304 c-state-cache-good-pos 1 4328 c-state-cache-good-pos 1
4329 c-state-cache-invalid-pos 1
4305 c-state-nonlit-pos-cache nil 4330 c-state-nonlit-pos-cache nil
4306 c-state-nonlit-pos-cache-limit 1 4331 c-state-nonlit-pos-cache-limit 1
4307 c-state-brace-pair-desert nil 4332 c-state-brace-pair-desert nil
@@ -4338,8 +4363,9 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4338 4363
4339(defun c-invalidate-state-cache-1 (here) 4364(defun c-invalidate-state-cache-1 (here)
4340 ;; Invalidate all info on `c-state-cache' that applies to the buffer at HERE 4365 ;; Invalidate all info on `c-state-cache' that applies to the buffer at HERE
4341 ;; or higher and set `c-state-cache-good-pos' accordingly. The cache is 4366 ;; or higher and set `c-state-cache-good-pos' and
4342 ;; left in a consistent state. 4367 ;; `c-state-cache-invalid-pos' accordingly. The cache is left in a
4368 ;; consistent state.
4343 ;; 4369 ;;
4344 ;; This is much like `c-whack-state-after', but it never changes a paren 4370 ;; This is much like `c-whack-state-after', but it never changes a paren
4345 ;; pair element into an open paren element. Doing that would mean that the 4371 ;; pair element into an open paren element. Doing that would mean that the
@@ -4353,7 +4379,6 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4353 ;; HERE. 4379 ;; HERE.
4354 (if (<= here c-state-nonlit-pos-cache-limit) 4380 (if (<= here c-state-nonlit-pos-cache-limit)
4355 (setq c-state-nonlit-pos-cache-limit (1- here))) 4381 (setq c-state-nonlit-pos-cache-limit (1- here)))
4356 (c-truncate-lit-pos-cache here)
4357 4382
4358 (cond 4383 (cond
4359 ;; `c-state-cache': 4384 ;; `c-state-cache':
@@ -4363,6 +4388,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4363 (< here (c-state-get-min-scan-pos))) 4388 (< here (c-state-get-min-scan-pos)))
4364 (setq c-state-cache nil 4389 (setq c-state-cache nil
4365 c-state-cache-good-pos nil 4390 c-state-cache-good-pos nil
4391 c-state-cache-invalid-pos (c-state-get-min-scan-pos)
4366 c-state-min-scan-pos nil)) 4392 c-state-min-scan-pos nil))
4367 4393
4368 ;; Case 2: `here' is below `c-state-cache-good-pos', so we need to amend 4394 ;; Case 2: `here' is below `c-state-cache-good-pos', so we need to amend
@@ -4377,7 +4403,9 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4377 (setq c-state-cache-good-pos 4403 (setq c-state-cache-good-pos
4378 (if scan-forward-p 4404 (if scan-forward-p
4379 (c-append-to-state-cache good-pos here) 4405 (c-append-to-state-cache good-pos here)
4380 good-pos))))) 4406 good-pos)
4407 c-state-cache-invalid-pos
4408 (or c-state-cache-good-pos (c-state-get-min-scan-pos))))))
4381 4409
4382 ;; The brace-pair desert marker: 4410 ;; The brace-pair desert marker:
4383 (when (car c-state-brace-pair-desert) 4411 (when (car c-state-brace-pair-desert)
@@ -4474,7 +4502,8 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4474 (if (and bopl-state 4502 (if (and bopl-state
4475 (< good-pos (- here c-state-cache-too-far))) 4503 (< good-pos (- here c-state-cache-too-far)))
4476 (c-state-cache-lower-good-pos here here-bopl bopl-state) 4504 (c-state-cache-lower-good-pos here here-bopl bopl-state)
4477 good-pos))) 4505 good-pos)
4506 c-state-cache-invalid-pos c-state-cache-good-pos))
4478 4507
4479 ((eq strategy 'backward) 4508 ((eq strategy 'backward)
4480 (setq res (c-remove-stale-state-cache-backwards here) 4509 (setq res (c-remove-stale-state-cache-backwards here)
@@ -4486,7 +4515,8 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4486 (setq c-state-cache-good-pos 4515 (setq c-state-cache-good-pos
4487 (if scan-forward-p 4516 (if scan-forward-p
4488 (c-append-to-state-cache good-pos here) 4517 (c-append-to-state-cache good-pos here)
4489 good-pos))) 4518 good-pos)
4519 c-state-cache-invalid-pos c-state-cache-good-pos))
4490 4520
4491 (t ; (eq strategy 'IN-LIT) 4521 (t ; (eq strategy 'IN-LIT)
4492 (setq c-state-cache nil 4522 (setq c-state-cache nil
@@ -4494,7 +4524,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4494 4524
4495 c-state-cache) 4525 c-state-cache)
4496 4526
4497(defun c-invalidate-state-cache (here) 4527(defun c-invalidate-state-cache ()
4498 ;; This is a wrapper over `c-invalidate-state-cache-1'. 4528 ;; This is a wrapper over `c-invalidate-state-cache-1'.
4499 ;; 4529 ;;
4500 ;; It suppresses the syntactic effect of the < and > (template) brackets and 4530 ;; It suppresses the syntactic effect of the < and > (template) brackets and
@@ -4504,9 +4534,9 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4504 (if (eval-when-compile (memq 'category-properties c-emacs-features)) 4534 (if (eval-when-compile (memq 'category-properties c-emacs-features))
4505 ;; Emacs 4535 ;; Emacs
4506 (c-with-<->-as-parens-suppressed 4536 (c-with-<->-as-parens-suppressed
4507 (c-invalidate-state-cache-1 here)) 4537 (c-invalidate-state-cache-1 c-state-cache-invalid-pos))
4508 ;; XEmacs 4538 ;; XEmacs
4509 (c-invalidate-state-cache-1 here))) 4539 (c-invalidate-state-cache-1 c-state-cache-invalid-pos)))
4510 4540
4511(defmacro c-state-maybe-marker (place marker) 4541(defmacro c-state-maybe-marker (place marker)
4512 ;; If PLACE is non-nil, return a marker marking it, otherwise nil. 4542 ;; If PLACE is non-nil, return a marker marking it, otherwise nil.
@@ -4539,8 +4569,14 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4539 (if (eval-when-compile (memq 'category-properties c-emacs-features)) 4569 (if (eval-when-compile (memq 'category-properties c-emacs-features))
4540 ;; Emacs 4570 ;; Emacs
4541 (c-with-<->-as-parens-suppressed 4571 (c-with-<->-as-parens-suppressed
4572 (when (< c-state-cache-invalid-pos
4573 (or c-state-cache-good-pos (c-state-get-min-scan-pos)))
4574 (c-invalidate-state-cache-1 c-state-cache-invalid-pos))
4542 (c-parse-state-1)) 4575 (c-parse-state-1))
4543 ;; XEmacs 4576 ;; XEmacs
4577 (when (< c-state-cache-invalid-pos
4578 (or c-state-cache-good-pos (c-state-get-min-scan-pos)))
4579 (c-invalidate-state-cache-1 c-state-cache-invalid-pos))
4544 (c-parse-state-1)) 4580 (c-parse-state-1))
4545 (setq c-state-old-cpp-beg 4581 (setq c-state-old-cpp-beg
4546 (c-state-maybe-marker here-cpp-beg c-state-old-cpp-beg-marker) 4582 (c-state-maybe-marker here-cpp-beg c-state-old-cpp-beg-marker)
@@ -4572,6 +4608,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4572 (t val))))) 4608 (t val)))))
4573 '(c-state-cache 4609 '(c-state-cache
4574 c-state-cache-good-pos 4610 c-state-cache-good-pos
4611 c-state-cache-invalid-pos
4575 c-state-nonlit-pos-cache 4612 c-state-nonlit-pos-cache
4576 c-state-nonlit-pos-cache-limit 4613 c-state-nonlit-pos-cache-limit
4577 c-state-brace-pair-desert 4614 c-state-brace-pair-desert
@@ -4609,6 +4646,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and
4609 (let ((here (point)) (min-point (point-min)) (res1 (c-real-parse-state)) res2) 4646 (let ((here (point)) (min-point (point-min)) (res1 (c-real-parse-state)) res2)
4610 (let ((c-state-cache nil) 4647 (let ((c-state-cache nil)
4611 (c-state-cache-good-pos 1) 4648 (c-state-cache-good-pos 1)
4649 (c-state-cache-invalid-pos 1)
4612 (c-state-nonlit-pos-cache nil) 4650 (c-state-nonlit-pos-cache nil)
4613 (c-state-nonlit-pos-cache-limit 1) 4651 (c-state-nonlit-pos-cache-limit 1)
4614 (c-state-brace-pair-desert nil) 4652 (c-state-brace-pair-desert nil)
@@ -6999,9 +7037,9 @@ comment at the start of cc-engine.el for more info."
6999 (when (equal (c-get-char-property (1- (point)) 'syntax-table) 7037 (when (equal (c-get-char-property (1- (point)) 'syntax-table)
7000 c->-as-paren-syntax) ; should always be true. 7038 c->-as-paren-syntax) ; should always be true.
7001 (c-unmark-<->-as-paren (1- (point))) 7039 (c-unmark-<->-as-paren (1- (point)))
7002 (c-truncate-lit-pos-cache (1- (point)))) 7040 (c-truncate-lit-pos/state-cache (1- (point))))
7003 (c-unmark-<->-as-paren pos) 7041 (c-unmark-<->-as-paren pos)
7004 (c-truncate-lit-pos-cache pos)))) 7042 (c-truncate-lit-pos/state-cache pos))))
7005 7043
7006(defun c-clear->-pair-props (&optional pos) 7044(defun c-clear->-pair-props (&optional pos)
7007 ;; POS (default point) is at a > character. If it is marked with 7045 ;; POS (default point) is at a > character. If it is marked with
@@ -7018,9 +7056,9 @@ comment at the start of cc-engine.el for more info."
7018 (when (equal (c-get-char-property (point) 'syntax-table) 7056 (when (equal (c-get-char-property (point) 'syntax-table)
7019 c-<-as-paren-syntax) ; should always be true. 7057 c-<-as-paren-syntax) ; should always be true.
7020 (c-unmark-<->-as-paren (point)) 7058 (c-unmark-<->-as-paren (point))
7021 (c-truncate-lit-pos-cache (point))) 7059 (c-truncate-lit-pos/state-cache (point)))
7022 (c-unmark-<->-as-paren pos) 7060 (c-unmark-<->-as-paren pos)
7023 (c-truncate-lit-pos-cache pos)))) 7061 (c-truncate-lit-pos/state-cache pos))))
7024 7062
7025(defun c-clear-<>-pair-props (&optional pos) 7063(defun c-clear-<>-pair-props (&optional pos)
7026 ;; POS (default point) is at a < or > character. If it has an 7064 ;; POS (default point) is at a < or > character. If it has an
@@ -7054,7 +7092,7 @@ comment at the start of cc-engine.el for more info."
7054 c->-as-paren-syntax)) ; should always be true. 7092 c->-as-paren-syntax)) ; should always be true.
7055 (c-unmark-<->-as-paren (1- (point))) 7093 (c-unmark-<->-as-paren (1- (point)))
7056 (c-unmark-<->-as-paren pos) 7094 (c-unmark-<->-as-paren pos)
7057 (c-truncate-lit-pos-cache pos) 7095 (c-truncate-lit-pos/state-cache pos)
7058 (point))))) 7096 (point)))))
7059 7097
7060(defun c-clear->-pair-props-if-match-before (lim &optional pos) 7098(defun c-clear->-pair-props-if-match-before (lim &optional pos)
@@ -7075,7 +7113,7 @@ comment at the start of cc-engine.el for more info."
7075 (equal (c-get-char-property (point) 'syntax-table) 7113 (equal (c-get-char-property (point) 'syntax-table)
7076 c-<-as-paren-syntax)) ; should always be true. 7114 c-<-as-paren-syntax)) ; should always be true.
7077 (c-unmark-<->-as-paren (point)) 7115 (c-unmark-<->-as-paren (point))
7078 (c-truncate-lit-pos-cache (point)) 7116 (c-truncate-lit-pos/state-cache (point))
7079 (c-unmark-<->-as-paren pos) 7117 (c-unmark-<->-as-paren pos)
7080 (point))))) 7118 (point)))))
7081 7119
@@ -7194,7 +7232,8 @@ comment at the start of cc-engine.el for more info."
7194 (not (eq beg-literal-end end-literal-end)) 7232 (not (eq beg-literal-end end-literal-end))
7195 (skip-chars-forward "\\\\") 7233 (skip-chars-forward "\\\\")
7196 (eq (char-after) ?\n) 7234 (eq (char-after) ?\n)
7197 (not (zerop (skip-chars-backward "\\\\")))) 7235 (not (zerop (skip-chars-backward "\\\\")))
7236 (< (point) end))
7198 (setq swap-open-string-ends t) 7237 (setq swap-open-string-ends t)
7199 (if (c-get-char-property (1- beg-literal-end) 7238 (if (c-get-char-property (1- beg-literal-end)
7200 'syntax-table) 7239 'syntax-table)
@@ -7500,16 +7539,11 @@ multi-line strings (but not C++, for example)."
7500 ;; Remove any syntax-table text properties from the multi-line string 7539 ;; Remove any syntax-table text properties from the multi-line string
7501 ;; delimiters specified by STRING-DELIMS, the output of 7540 ;; delimiters specified by STRING-DELIMS, the output of
7502 ;; `c-ml-string-delims-around-point'. 7541 ;; `c-ml-string-delims-around-point'.
7503 (let (found) 7542 (c-clear-syntax-table-properties-trim-caches (caar string-delims)
7504 (if (setq found (c-clear-char-properties (caar string-delims) 7543 (cadar string-delims))
7505 (cadar string-delims)
7506 'syntax-table))
7507 (c-truncate-lit-pos-cache found))
7508 (when (cdr string-delims) 7544 (when (cdr string-delims)
7509 (if (setq found (c-clear-char-properties (cadr string-delims) 7545 (c-clear-syntax-table-properties-trim-caches (cadr string-delims)
7510 (caddr string-delims) 7546 (caddr string-delims))))
7511 'syntax-table))
7512 (c-truncate-lit-pos-cache found)))))
7513 7547
7514(defun c-get-ml-closer (open-delim) 7548(defun c-get-ml-closer (open-delim)
7515 ;; Return the closer, a three element dotted list of the closer's start, its 7549 ;; Return the closer, a three element dotted list of the closer's start, its
@@ -7943,7 +7977,7 @@ multi-line strings (but not C++, for example)."
7943 ((eq (nth 3 (car state)) t) 7977 ((eq (nth 3 (car state)) t)
7944 (insert ?\") 7978 (insert ?\")
7945 (c-put-string-fence end))) 7979 (c-put-string-fence end)))
7946 (c-truncate-lit-pos-cache end) 7980 (c-truncate-lit-pos/state-cache end)
7947 ;; ....ensure c-new-END extends right to the end of the about 7981 ;; ....ensure c-new-END extends right to the end of the about
7948 ;; to be un-stringed raw string.... 7982 ;; to be un-stringed raw string....
7949 (save-excursion 7983 (save-excursion
@@ -7963,7 +7997,7 @@ multi-line strings (but not C++, for example)."
7963 ;; Remove the temporary string delimiter. 7997 ;; Remove the temporary string delimiter.
7964 (goto-char end) 7998 (goto-char end)
7965 (delete-char 1) 7999 (delete-char 1)
7966 (c-truncate-lit-pos-cache end)))) 8000 (c-truncate-lit-pos/state-cache end))))
7967 8001
7968 ;; Have we just created a new starting id? 8002 ;; Have we just created a new starting id?
7969 (goto-char beg) 8003 (goto-char beg)
@@ -8013,7 +8047,7 @@ multi-line strings (but not C++, for example)."
8013 (> (point) beg))) 8047 (> (point) beg)))
8014 (goto-char (caar c-old-1-beg-ml)) 8048 (goto-char (caar c-old-1-beg-ml))
8015 (setq c-new-BEG (min c-new-BEG (point))) 8049 (setq c-new-BEG (min c-new-BEG (point)))
8016 (c-truncate-lit-pos-cache (point)))) 8050 (c-truncate-lit-pos/state-cache (point))))
8017 8051
8018 (when (looking-at c-ml-string-opener-re) 8052 (when (looking-at c-ml-string-opener-re)
8019 (goto-char (match-end 1)) 8053 (goto-char (match-end 1))
@@ -8026,11 +8060,8 @@ multi-line strings (but not C++, for example)."
8026 (when (c-get-char-property (match-beginning 2) 'c-fl-syn-tab) 8060 (when (c-get-char-property (match-beginning 2) 'c-fl-syn-tab)
8027 (c-remove-string-fences (match-beginning 2))) 8061 (c-remove-string-fences (match-beginning 2)))
8028 (setq c-new-END (point-max)) 8062 (setq c-new-END (point-max))
8029 (c-clear-char-properties (caar (or c-old-beg-ml c-old-1-beg-ml)) 8063 (c-clear-syntax-table-properties-trim-caches
8030 c-new-END 8064 (caar (or c-old-beg-ml c-old-1-beg-ml)) c-new-END))))
8031 'syntax-table)
8032 (c-truncate-lit-pos-cache
8033 (caar (or c-old-beg-ml c-old-1-beg-ml))))))
8034 8065
8035 ;; Have we disturbed the innards of an ml string, possibly by deleting "s? 8066 ;; Have we disturbed the innards of an ml string, possibly by deleting "s?
8036 (when (and 8067 (when (and
@@ -8056,10 +8087,9 @@ multi-line strings (but not C++, for example)."
8056 bound 'bound) 8087 bound 'bound)
8057 (< (match-end 1) new-END-end-ml-string)) 8088 (< (match-end 1) new-END-end-ml-string))
8058 (setq c-new-END (max new-END-end-ml-string c-new-END)) 8089 (setq c-new-END (max new-END-end-ml-string c-new-END))
8059 (c-clear-char-properties (caar c-old-beg-ml) c-new-END 8090 (c-clear-syntax-table-properties-trim-caches
8060 'syntax-table) 8091 (caar c-old-beg-ml) c-new-END)
8061 (setq c-new-BEG (min (caar c-old-beg-ml) c-new-BEG)) 8092 (setq c-new-BEG (min (caar c-old-beg-ml) c-new-BEG)))))
8062 (c-truncate-lit-pos-cache (caar c-old-beg-ml)))))
8063 8093
8064 ;; Have we terminated an existing raw string by inserting or removing 8094 ;; Have we terminated an existing raw string by inserting or removing
8065 ;; text? 8095 ;; text?
@@ -8093,7 +8123,7 @@ multi-line strings (but not C++, for example)."
8093 (setq c-new-BEG (min (point) c-new-BEG) 8123 (setq c-new-BEG (min (point) c-new-BEG)
8094 c-new-END (point-max)) 8124 c-new-END (point-max))
8095 (c-clear-syn-tab-properties (point) c-new-END) 8125 (c-clear-syn-tab-properties (point) c-new-END)
8096 (c-truncate-lit-pos-cache (point))))) 8126 (c-truncate-lit-pos/state-cache (point)))))
8097 8127
8098 ;; Are there any raw strings in a newly created macro? 8128 ;; Are there any raw strings in a newly created macro?
8099 (goto-char (c-point 'bol beg)) 8129 (goto-char (c-point 'bol beg))
@@ -8147,8 +8177,7 @@ multi-line strings (but not C++, for example)."
8147 (cadr delim)) 8177 (cadr delim))
8148 (< (point) (cadr delim))) 8178 (< (point) (cadr delim)))
8149 (when (not (eq (point) (cddr delim))) 8179 (when (not (eq (point) (cddr delim)))
8150 (c-put-char-property (point) 'syntax-table '(1)) 8180 (c-put-syntax-table-trim-caches (point) '(1)))
8151 (c-truncate-lit-pos-cache (point)))
8152 (forward-char)))) 8181 (forward-char))))
8153 8182
8154(defun c-propertize-ml-string-opener (delim bound) 8183(defun c-propertize-ml-string-opener (delim bound)
@@ -8181,14 +8210,12 @@ multi-line strings (but not C++, for example)."
8181 (while (progn (skip-syntax-forward c-ml-string-non-punc-skip-chars 8210 (while (progn (skip-syntax-forward c-ml-string-non-punc-skip-chars
8182 (car end-delim)) 8211 (car end-delim))
8183 (< (point) (car end-delim))) 8212 (< (point) (car end-delim)))
8184 (c-put-char-property (point) 'syntax-table '(1)) ; punctuation 8213 (c-put-syntax-table-trim-caches (point) '(1)) ; punctuation
8185 (c-truncate-lit-pos-cache (point))
8186 (forward-char)) 8214 (forward-char))
8187 (goto-char (cadr end-delim)) 8215 (goto-char (cadr end-delim))
8188 t) 8216 t)
8189 (c-put-char-property (cddr delim) 'syntax-table '(1)) 8217 (c-put-syntax-table-trim-caches (cddr delim) '(1))
8190 (c-put-string-fence (1- (cadr delim))) 8218 (c-put-string-fence (1- (cadr delim)))
8191 (c-truncate-lit-pos-cache (1- (cddr delim)))
8192 (when bound 8219 (when bound
8193 ;; In a CPP construct, we try to apply a generic-string 8220 ;; In a CPP construct, we try to apply a generic-string
8194 ;; `syntax-table' text property to the last possible character in 8221 ;; `syntax-table' text property to the last possible character in
@@ -8218,10 +8245,9 @@ multi-line strings (but not C++, for example)."
8218 (if (match-beginning 10) 8245 (if (match-beginning 10)
8219 (progn 8246 (progn
8220 (c-put-string-fence (match-beginning 10)) 8247 (c-put-string-fence (match-beginning 10))
8221 (c-truncate-lit-pos-cache (match-beginning 10))) 8248 (c-truncate-lit-pos/state-cache (match-beginning 10)))
8222 (c-put-char-property (match-beginning 5) 'syntax-table '(1)) 8249 (c-put-syntax-table-trim-caches (match-beginning 5) '(1))
8223 (c-put-string-fence (1+ (match-beginning 5))) 8250 (c-put-string-fence (1+ (match-beginning 5)))))
8224 (c-truncate-lit-pos-cache (match-beginning 5))))
8225 (goto-char bound)) 8251 (goto-char bound))
8226 nil)) 8252 nil))
8227 8253
@@ -8261,20 +8287,18 @@ multi-line strings (but not C++, for example)."
8261 '(15))) 8287 '(15)))
8262 (goto-char (cdddr string-delims)) 8288 (goto-char (cdddr string-delims))
8263 (when (c-safe (c-forward-sexp)) ; To '(15) at EOL. 8289 (when (c-safe (c-forward-sexp)) ; To '(15) at EOL.
8264 (c-clear-char-property (1- (point)) 'syntax-table) 8290 (c-clear-syntax-table-trim-caches (1- (point)))))
8265 (c-truncate-lit-pos-cache (1- (point)))))
8266 ;; The '(15) in the closing delimiter will be cleared by the following. 8291 ;; The '(15) in the closing delimiter will be cleared by the following.
8267 8292
8268 (c-depropertize-ml-string-delims string-delims) 8293 (c-depropertize-ml-string-delims string-delims)
8269 (let ((bound1 (if (cdr string-delims) 8294 (let ((bound1 (if (cdr string-delims)
8270 (caddr string-delims) ; end of closing delimiter. 8295 (caddr string-delims) ; end of closing delimiter.
8271 bound)) 8296 bound))
8272 first s) 8297 s)
8273 (if (and 8298 (if bound1
8274 bound1 8299 (c-clear-syntax-table-properties-trim-caches
8275 (setq first (c-clear-char-properties (cadar string-delims) bound1 8300 (cadar string-delims) bound1))
8276 'syntax-table))) 8301
8277 (c-truncate-lit-pos-cache first))
8278 (setq s (parse-partial-sexp (or c-neutralize-pos (caar string-delims)) 8302 (setq s (parse-partial-sexp (or c-neutralize-pos (caar string-delims))
8279 (or bound1 (point-max)))) 8303 (or bound1 (point-max))))
8280 (cond 8304 (cond
@@ -8283,15 +8307,13 @@ multi-line strings (but not C++, for example)."
8283 (setq c-neutralize-pos (nth 8 s)) 8307 (setq c-neutralize-pos (nth 8 s))
8284 (setq c-neutralized-prop (c-get-char-property c-neutralize-pos 8308 (setq c-neutralized-prop (c-get-char-property c-neutralize-pos
8285 'syntax-table)) 8309 'syntax-table))
8286 (c-put-char-property c-neutralize-pos 'syntax-table '(1)) 8310 (c-put-syntax-table-trim-caches c-neutralize-pos '(1)))
8287 (c-truncate-lit-pos-cache c-neutralize-pos))
8288 ((eq (nth 3 s) (char-after c-neutralize-pos)) 8311 ((eq (nth 3 s) (char-after c-neutralize-pos))
8289 ;; New unbalanced quote balances old one. 8312 ;; New unbalanced quote balances old one.
8290 (if c-neutralized-prop 8313 (if c-neutralized-prop
8291 (c-put-char-property c-neutralize-pos 'syntax-table 8314 (c-put-syntax-table-trim-caches c-neutralize-pos
8292 c-neutralized-prop) 8315 c-neutralized-prop)
8293 (c-clear-char-property c-neutralize-pos 'syntax-table)) 8316 (c-clear-syntax-table-trim-caches c-neutralize-pos))
8294 (c-truncate-lit-pos-cache c-neutralize-pos)
8295 (setq c-neutralize-pos nil)) 8317 (setq c-neutralize-pos nil))
8296 ;; New unbalanced quote doesn't balance old one. Nothing to do. 8318 ;; New unbalanced quote doesn't balance old one. Nothing to do.
8297 ))) 8319 )))
@@ -8350,10 +8372,8 @@ multi-line strings (but not C++, for example)."
8350 eom))))))) ; bound. 8372 eom))))))) ; bound.
8351 (when c-neutralize-pos 8373 (when c-neutralize-pos
8352 (if c-neutralized-prop 8374 (if c-neutralized-prop
8353 (c-put-char-property c-neutralize-pos 'syntax-table 8375 (c-put-syntax-table-trim-caches c-neutralize-pos c-neutralized-prop)
8354 c-neutralized-prop) 8376 (c-clear-syntax-table-trim-caches c-neutralize-pos))))
8355 (c-clear-char-property c-neutralize-pos 'syntax-table))
8356 (c-truncate-lit-pos-cache c-neutralize-pos)))
8357 8377
8358 8378
8359(defun c-before-after-change-check-c++-modules (beg end &optional _old_len) 8379(defun c-before-after-change-check-c++-modules (beg end &optional _old_len)
@@ -8793,7 +8813,7 @@ multi-line strings (but not C++, for example)."
8793 (when c-parse-and-markup-<>-arglists 8813 (when c-parse-and-markup-<>-arglists
8794 (c-mark-<-as-paren (point)) 8814 (c-mark-<-as-paren (point))
8795 (c-mark->-as-paren (match-beginning 1)) 8815 (c-mark->-as-paren (match-beginning 1))
8796 (c-truncate-lit-pos-cache (point))) 8816 (c-truncate-lit-pos/state-cache (point)))
8797 (goto-char (match-end 1)) 8817 (goto-char (match-end 1))
8798 t) 8818 t)
8799 nil)) 8819 nil))
@@ -8927,11 +8947,11 @@ multi-line strings (but not C++, for example)."
8927 (save-excursion 8947 (save-excursion
8928 (and (c-go-list-backward) 8948 (and (c-go-list-backward)
8929 (eq (char-after) ?<) 8949 (eq (char-after) ?<)
8930 (c-truncate-lit-pos-cache (point)) 8950 (c-truncate-lit-pos/state-cache (point))
8931 (c-unmark-<->-as-paren (point))))) 8951 (c-unmark-<->-as-paren (point)))))
8932 (c-mark-<-as-paren start) 8952 (c-mark-<-as-paren start)
8933 (c-mark->-as-paren (1- (point))) 8953 (c-mark->-as-paren (1- (point)))
8934 (c-truncate-lit-pos-cache start)) 8954 (c-truncate-lit-pos/state-cache start))
8935 (setq res t) 8955 (setq res t)
8936 nil)) ; Exit the loop. 8956 nil)) ; Exit the loop.
8937 8957
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index fe3ddaa170f..71fafeca59f 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -658,7 +658,7 @@ that requires a literal mode spec at compile time."
658 ;; Initialize the cache for `c-looking-at-or-maybe-in-bracelist'. 658 ;; Initialize the cache for `c-looking-at-or-maybe-in-bracelist'.
659 (setq c-laomib-cache nil) 659 (setq c-laomib-cache nil)
660 ;; Initialize the three literal sub-caches. 660 ;; Initialize the three literal sub-caches.
661 (c-truncate-lit-pos-cache 1) 661 (c-truncate-lit-pos/state-cache 1)
662 ;; Initialize the cache of brace pairs, and opening braces/brackets/parens. 662 ;; Initialize the cache of brace pairs, and opening braces/brackets/parens.
663 (c-state-cache-init) 663 (c-state-cache-init)
664 ;; Initialize the "brace stack" cache. 664 ;; Initialize the "brace stack" cache.
@@ -1023,8 +1023,8 @@ Note that the style variables are always made local to the buffer."
1023 (setq m-beg (point)) 1023 (setq m-beg (point))
1024 (c-end-of-macro) 1024 (c-end-of-macro)
1025 (when c-ml-string-opener-re 1025 (when c-ml-string-opener-re
1026 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point)))) 1026 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point)))
1027 (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) 1027 (c-clear-syntax-table-with-value-trim-caches m-beg (point) '(1))))
1028 1028
1029 (while (and (< (point) end) 1029 (while (and (< (point) end)
1030 (setq ss-found 1030 (setq ss-found
@@ -1035,17 +1035,17 @@ Note that the style variables are always made local to the buffer."
1035 (when (and ss-found (> (point) end)) 1035 (when (and ss-found (> (point) end))
1036 (when c-ml-string-opener-re 1036 (when c-ml-string-opener-re
1037 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point)))) 1037 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point))))
1038 (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) 1038 (c-clear-syntax-table-with-value-trim-caches m-beg (point) '(1)))
1039 1039
1040 (while (and (< (point) c-new-END) 1040 (while (and (< (point) c-new-END)
1041 (search-forward-regexp c-anchored-cpp-prefix c-new-END 'bound)) 1041 (search-forward-regexp c-anchored-cpp-prefix
1042 c-new-END 'bound))
1042 (goto-char (match-beginning 1)) 1043 (goto-char (match-beginning 1))
1043 (setq m-beg (point)) 1044 (setq m-beg (point))
1044 (c-end-of-macro) 1045 (c-end-of-macro)
1045 (when c-ml-string-opener-re 1046 (when c-ml-string-opener-re
1046 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point)))) 1047 (save-excursion (c-depropertize-ml-strings-in-region m-beg (point))))
1047 (c-clear-char-property-with-value 1048 (c-clear-syntax-table-with-value-trim-caches m-beg (point) '(1)))))
1048 m-beg (point) 'syntax-table '(1)))))
1049 1049
1050(defun c-extend-region-for-CPP (_beg _end) 1050(defun c-extend-region-for-CPP (_beg _end)
1051 ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of 1051 ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of
@@ -1126,7 +1126,7 @@ Note that the style variables are always made local to the buffer."
1126 (setq s (parse-partial-sexp beg end -1)) 1126 (setq s (parse-partial-sexp beg end -1))
1127 (cond 1127 (cond
1128 ((< (nth 0 s) 0) ; found an unmated ),},] 1128 ((< (nth 0 s) 0) ; found an unmated ),},]
1129 (c-put-char-property (1- (point)) 'syntax-table '(1)) 1129 (c-put-syntax-table-trim-caches (1- (point)) '(1))
1130 t) 1130 t)
1131 ;; Unbalanced strings are now handled by 1131 ;; Unbalanced strings are now handled by
1132 ;; `c-before-change-check-unbalanced-strings', etc. 1132 ;; `c-before-change-check-unbalanced-strings', etc.
@@ -1134,7 +1134,7 @@ Note that the style variables are always made local to the buffer."
1134 ;; (c-put-char-property (nth 8 s) 'syntax-table '(1)) 1134 ;; (c-put-char-property (nth 8 s) 'syntax-table '(1))
1135 ;; t) 1135 ;; t)
1136 ((> (nth 0 s) 0) ; In a (,{,[ 1136 ((> (nth 0 s) 0) ; In a (,{,[
1137 (c-put-char-property (nth 1 s) 'syntax-table '(1)) 1137 (c-put-syntax-table-trim-caches (nth 1 s) '(1))
1138 t) 1138 t)
1139 (t nil))))))) 1139 (t nil)))))))
1140 1140
@@ -1284,7 +1284,7 @@ Note that the style variables are always made local to the buffer."
1284 ;; (-value- ,value)) 1284 ;; (-value- ,value))
1285 (if (equal value '(15)) 1285 (if (equal value '(15))
1286 (c-put-string-fence pos) 1286 (c-put-string-fence pos)
1287 (c-put-char-property pos 'syntax-table value)) 1287 (c-put-syntax-table-trim-caches pos value))
1288 (c-put-char-property pos 'c-fl-syn-tab value) 1288 (c-put-char-property pos 'c-fl-syn-tab value)
1289 (cond 1289 (cond
1290 ((null c-min-syn-tab-mkr) 1290 ((null c-min-syn-tab-mkr)
@@ -1295,12 +1295,11 @@ Note that the style variables are always made local to the buffer."
1295 ((null c-max-syn-tab-mkr) 1295 ((null c-max-syn-tab-mkr)
1296 (setq c-max-syn-tab-mkr (copy-marker (1+ pos) nil))) 1296 (setq c-max-syn-tab-mkr (copy-marker (1+ pos) nil)))
1297 ((>= pos c-max-syn-tab-mkr) 1297 ((>= pos c-max-syn-tab-mkr)
1298 (move-marker c-max-syn-tab-mkr (1+ pos)))) 1298 (move-marker c-max-syn-tab-mkr (1+ pos)))))
1299 (c-truncate-lit-pos-cache pos))
1300 1299
1301(defun c-clear-syn-tab (pos) 1300(defun c-clear-syn-tab (pos)
1302 ;; Remove both the 'syntax-table and `c-fl-syn-tab properties at POS. 1301 ;; Remove both the 'syntax-table and `c-fl-syn-tab properties at POS.
1303 (c-clear-char-property pos 'syntax-table) 1302 (c-clear-syntax-table-trim-caches pos)
1304 (c-clear-char-property pos 'c-fl-syn-tab) 1303 (c-clear-char-property pos 'c-fl-syn-tab)
1305 (when c-min-syn-tab-mkr 1304 (when c-min-syn-tab-mkr
1306 (if (and (eq pos (marker-position c-min-syn-tab-mkr)) 1305 (if (and (eq pos (marker-position c-min-syn-tab-mkr))
@@ -1321,12 +1320,15 @@ Note that the style variables are always made local to the buffer."
1321 pos 1320 pos
1322 (c-previous-single-property-change 1321 (c-previous-single-property-change
1323 pos 'c-fl-syn-tab nil (1+ c-min-syn-tab-mkr))))))) 1322 pos 'c-fl-syn-tab nil (1+ c-min-syn-tab-mkr)))))))
1324 (c-truncate-lit-pos-cache pos)) 1323 (c-truncate-lit-pos/state-cache pos))
1325 1324
1326(defun c-clear-string-fences () 1325(defun c-clear-string-fences ()
1327 ;; Clear syntax-table text properties which are "mirrored" by c-fl-syn-tab 1326 ;; Clear syntax-table text properties which are "mirrored" by c-fl-syn-tab
1328 ;; text properties. However, any such " character which ends up not being 1327 ;; text properties. However, any such " character which ends up not being
1329 ;; balanced by another " is left with a '(1) syntax-table property. 1328 ;; balanced by another " is left with a '(1) syntax-table property.
1329 ;; Note we don't truncate the caches in this function, since it is only
1330 ;; called before leaving CC Mode, and the text properties will be restored
1331 ;; by `c-restore-string-fences' before we continue in CC Mode.
1330 (when 1332 (when
1331 (and c-min-syn-tab-mkr c-max-syn-tab-mkr) 1333 (and c-min-syn-tab-mkr c-max-syn-tab-mkr)
1332 (c-save-buffer-state (s pos) ; Prevent text property stuff causing change 1334 (c-save-buffer-state (s pos) ; Prevent text property stuff causing change
@@ -1391,6 +1393,7 @@ Note that the style variables are always made local to the buffer."
1391(defun c-restore-string-fences () 1393(defun c-restore-string-fences ()
1392 ;; Restore any syntax-table text properties which are "mirrored" by 1394 ;; Restore any syntax-table text properties which are "mirrored" by
1393 ;; c-fl-syn-tab text properties. 1395 ;; c-fl-syn-tab text properties.
1396 ;; We don't truncate the caches here. See `c-clear-string-fences'.
1394 (when (and c-min-syn-tab-mkr c-max-syn-tab-mkr) 1397 (when (and c-min-syn-tab-mkr c-max-syn-tab-mkr)
1395 (c-save-buffer-state ; Prevent text property stuff causing change function 1398 (c-save-buffer-state ; Prevent text property stuff causing change function
1396 ; invocation. 1399 ; invocation.
@@ -1947,12 +1950,8 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1947 (goto-char c-new-BEG) 1950 (goto-char c-new-BEG)
1948 (when (c-search-forward-char-property-with-value-on-char 1951 (when (c-search-forward-char-property-with-value-on-char
1949 'syntax-table '(1) ?\' c-new-END) 1952 'syntax-table '(1) ?\' c-new-END)
1950 (c-invalidate-state-cache (1- (point))) 1953 (c-clear-syntax-table-with-value-on-char-trim-caches
1951 (c-truncate-lit-pos-cache (1- (point))) 1954 (1- (point)) c-new-END '(1) ?')
1952 (c-clear-char-property-with-value-on-char
1953 (1- (point)) c-new-END
1954 'syntax-table '(1)
1955 ?')
1956 ;; Remove the c-digit-separator text property from the same "'"s. 1955 ;; Remove the c-digit-separator text property from the same "'"s.
1957 (when c-has-quoted-numbers 1956 (when c-has-quoted-numbers
1958 (c-clear-char-property-with-value-on-char 1957 (c-clear-char-property-with-value-on-char
@@ -1979,10 +1978,8 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1979 ((c-quoted-number-straddling-point) 1978 ((c-quoted-number-straddling-point)
1980 (setq num-beg (match-beginning 0) 1979 (setq num-beg (match-beginning 0)
1981 num-end (match-end 0)) 1980 num-end (match-end 0))
1982 (c-invalidate-state-cache num-beg) 1981 (c-put-syntax-table-properties-on-char-trim-caches
1983 (c-truncate-lit-pos-cache num-beg) 1982 num-beg num-end '(1) ?')
1984 (c-put-char-properties-on-char num-beg num-end
1985 'syntax-table '(1) ?')
1986 (c-put-char-properties-on-char num-beg num-end 1983 (c-put-char-properties-on-char num-beg num-end
1987 'c-digit-separator t ?') 1984 'c-digit-separator t ?')
1988 (goto-char num-end)) 1985 (goto-char num-end))
@@ -1991,15 +1988,11 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1991\\)'") ; balanced quoted expression. 1988\\)'") ; balanced quoted expression.
1992 (goto-char (match-end 0))) 1989 (goto-char (match-end 0)))
1993 ((looking-at "\\\\'") ; Anomalous construct. 1990 ((looking-at "\\\\'") ; Anomalous construct.
1994 (c-invalidate-state-cache (1- (point))) 1991 (c-truncate-lit-pos/state-cache (1- (point)))
1995 (c-truncate-lit-pos-cache (1- (point))) 1992 (c-put-syntax-table-properties-on-char-trim-caches
1996 (c-put-char-properties-on-char (1- (point)) (+ (point) 2) 1993 (1- (point)) (+ (point) 2) '(1) ?'))
1997 'syntax-table '(1) ?')
1998 (goto-char (match-end 0)))
1999 (t 1994 (t
2000 (c-invalidate-state-cache (1- (point))) 1995 (c-put-syntax-table-trim-caches (1- (point)) '(1))))
2001 (c-truncate-lit-pos-cache (1- (point)))
2002 (c-put-char-property (1- (point)) 'syntax-table '(1))))
2003 ;; Prevent the next `c-quoted-number-straddling-point' getting 1996 ;; Prevent the next `c-quoted-number-straddling-point' getting
2004 ;; confused by already processed single quotes. 1997 ;; confused by already processed single quotes.
2005 (narrow-to-region (point) (point-max)))))) 1998 (narrow-to-region (point) (point-max))))))
@@ -2036,12 +2029,10 @@ with // and /*, not more generic line and block comments."
2036 (if (eq (cadr end-state) 'c) 2029 (if (eq (cadr end-state) 'c)
2037 (when (search-forward "\\*/" 2030 (when (search-forward "\\*/"
2038 (or (cdr (caddr end-state)) (point-max)) t) 2031 (or (cdr (caddr end-state)) (point-max)) t)
2039 (c-clear-char-property (match-beginning 0) 'syntax-table) 2032 (c-clear-syntax-table-trim-caches (match-beginning 0)))
2040 (c-truncate-lit-pos-cache (match-beginning 0)))
2041 (while (search-forward "\\\\\n" 2033 (while (search-forward "\\\\\n"
2042 (or (cdr (caddr end-state)) (point-max)) t) 2034 (or (cdr (caddr end-state)) (point-max)) t)
2043 (c-clear-char-property (match-beginning 0) 'syntax-table) 2035 (c-clear-syntax-table-trim-caches (match-beginning 0)))))))
2044 (c-truncate-lit-pos-cache (match-beginning 0)))))))
2045 2036
2046(defun c-after-change-fix-comment-escapes (beg end _old-len) 2037(defun c-after-change-fix-comment-escapes (beg end _old-len)
2047 "Apply punctuation syntax-table text properties to C/C++ comment markers. 2038 "Apply punctuation syntax-table text properties to C/C++ comment markers.
@@ -2073,8 +2064,7 @@ with // and /*, not more generic line and block comments."
2073 (match-beginning 3)) 2064 (match-beginning 3))
2074 ((eq (cadr state) 'c++) 2065 ((eq (cadr state) 'c++)
2075 (match-beginning 2))) 2066 (match-beginning 2)))
2076 (c-put-char-property (match-beginning 0) 'syntax-table '(1)) 2067 (c-put-syntax-table-trim-caches (match-beginning 0) '(1))))
2077 (c-truncate-lit-pos-cache (match-beginning 0))))
2078 2068
2079 (goto-char end) 2069 (goto-char end)
2080 (setq state (c-semi-pp-to-literal (point))) 2070 (setq state (c-semi-pp-to-literal (point)))
@@ -2082,8 +2072,7 @@ with // and /*, not more generic line and block comments."
2082 ((eq (cadr state) 'c) 2072 ((eq (cadr state) 'c)
2083 (when (search-forward "*/" nil t) 2073 (when (search-forward "*/" nil t)
2084 (when (eq (char-before (match-beginning 0)) ?\\) 2074 (when (eq (char-before (match-beginning 0)) ?\\)
2085 (c-put-char-property (1- (match-beginning 0)) 'syntax-table '(1)) 2075 (c-put-syntax-table-trim-caches (1- (match-beginning 0)) '(1)))))
2086 (c-truncate-lit-pos-cache (1- (match-beginning 0))))))
2087 ((eq (cadr state) 'c++) 2076 ((eq (cadr state) 'c++)
2088 (while 2077 (while
2089 (progn 2078 (progn
@@ -2091,8 +2080,7 @@ with // and /*, not more generic line and block comments."
2091 (and (eq (char-before) ?\\) 2080 (and (eq (char-before) ?\\)
2092 (progn 2081 (progn
2093 (when (eq (char-before (1- (point))) ?\\) 2082 (when (eq (char-before (1- (point))) ?\\)
2094 (c-put-char-property (- (point) 2) 'syntax-table '(1)) 2083 (c-put-syntax-table-trim-caches (- (point) 2) '(1)))
2095 (c-truncate-lit-pos-cache (1- (point))))
2096 t) 2084 t)
2097 (not (eobp)))) 2085 (not (eobp))))
2098 (forward-char)))))) 2086 (forward-char))))))
@@ -2278,11 +2266,11 @@ with // and /*, not more generic line and block comments."
2278 c-get-state-before-change-functions)) 2266 c-get-state-before-change-functions))
2279 2267
2280 (c-laomib-invalidate-cache beg end)))) 2268 (c-laomib-invalidate-cache beg end))))
2281 (c-truncate-lit-pos-cache beg) 2269 (c-truncate-lit-pos/state-cache beg)
2282 ;; The following must be done here rather than in `c-after-change' 2270 ;; The following must be done here rather than in `c-after-change'
2283 ;; because newly inserted parens would foul up the invalidation 2271 ;; because newly inserted parens would foul up the invalidation
2284 ;; algorithm. 2272 ;; algorithm.
2285 (c-invalidate-state-cache beg) 2273 (c-invalidate-state-cache)
2286 ;; The following must happen after the previous, which likely alters 2274 ;; The following must happen after the previous, which likely alters
2287 ;; the macro cache. 2275 ;; the macro cache.
2288 (when c-opt-cpp-symbol 2276 (when c-opt-cpp-symbol