diff options
| author | Alan Mackenzie | 2016-05-16 11:27:39 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2016-05-16 11:27:39 +0000 |
| commit | 116acebfbd28649b6ccf34e5c9046738d57aa28e (patch) | |
| tree | bc1bd43469ba4fdbe316d709bdeb4d9e85fe45bf | |
| parent | 65c8c7cb96c14f9c6accd03cc8851b5a3459049e (diff) | |
| download | emacs-116acebfbd28649b6ccf34e5c9046738d57aa28e.tar.gz emacs-116acebfbd28649b6ccf34e5c9046738d57aa28e.zip | |
Fix spurious fontification of "for (; a * b;)" in CC Mode.
This fixes bug #7918 (again).
* lisp/progmodes/cc-engine.el (c-delq-from-dotted-list): New function.
(c-forward-decl-or-cast-1): Return a 4 element list in place of the previous
cons cell - additionally, return a flag indicating whether the declaration
parsed might have been an expression, and the position of the type identifier
in the said declaration.
* lisp/progmodes/cc-fonts.el (c-font-lock-declarations): When
c-forward-decl-or-cast-1 has indicated it might have parsed an expression,
check for it being a spurious declaration in a "for" statement.
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 44 | ||||
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 32 |
2 files changed, 66 insertions, 10 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index d19d2dacda1..2450a5db8b9 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -385,6 +385,25 @@ comment at the start of cc-engine.el for more info." | |||
| 385 | 385 | ||
| 386 | ;;; Basic utility functions. | 386 | ;;; Basic utility functions. |
| 387 | 387 | ||
| 388 | (defun c-delq-from-dotted-list (elt dlist) | ||
| 389 | ;; If ELT is a member of the (possibly dotted) list DLIST, remove all | ||
| 390 | ;; occurrences of it (except for any in the last cdr of DLIST). | ||
| 391 | ;; | ||
| 392 | ;; Call this as (setq DLIST (c-delq-from-dotted-list ELT DLIST)), as | ||
| 393 | ;; sometimes the original structure is changed, sometimes it's not. | ||
| 394 | ;; | ||
| 395 | ;; This function is needed in Emacs < 24.5, and possibly XEmacs, because | ||
| 396 | ;; `delq' throws an error in these versions when given a dotted list. | ||
| 397 | (let ((tail dlist) prev) | ||
| 398 | (while (consp tail) | ||
| 399 | (if (eq (car tail) elt) | ||
| 400 | (if prev | ||
| 401 | (setcdr prev (cdr tail)) | ||
| 402 | (setq dlist (cdr dlist))) | ||
| 403 | (setq prev tail)) | ||
| 404 | (setq tail (cdr tail))) | ||
| 405 | dlist)) | ||
| 406 | |||
| 388 | (defun c-syntactic-content (from to paren-level) | 407 | (defun c-syntactic-content (from to paren-level) |
| 389 | ;; Return the given region as a string where all syntactic | 408 | ;; Return the given region as a string where all syntactic |
| 390 | ;; whitespace is removed or, where necessary, replaced with a single | 409 | ;; whitespace is removed or, where necessary, replaced with a single |
| @@ -7020,9 +7039,9 @@ comment at the start of cc-engine.el for more info." | |||
| 7020 | ;; If a declaration is parsed: | 7039 | ;; If a declaration is parsed: |
| 7021 | ;; | 7040 | ;; |
| 7022 | ;; The point is left at the first token after the first complete | 7041 | ;; The point is left at the first token after the first complete |
| 7023 | ;; declarator, if there is one. The return value is a cons where | 7042 | ;; declarator, if there is one. The return value is a list of 4 elements, |
| 7024 | ;; the car is the position of the first token in the declarator. (See | 7043 | ;; where the first is the position of the first token in the declarator. |
| 7025 | ;; below for the cdr.) | 7044 | ;; (See below for the other three.) |
| 7026 | ;; Some examples: | 7045 | ;; Some examples: |
| 7027 | ;; | 7046 | ;; |
| 7028 | ;; void foo (int a, char *b) stuff ... | 7047 | ;; void foo (int a, char *b) stuff ... |
| @@ -7053,7 +7072,7 @@ comment at the start of cc-engine.el for more info." | |||
| 7053 | ;; | 7072 | ;; |
| 7054 | ;; | 7073 | ;; |
| 7055 | ;; | 7074 | ;; |
| 7056 | ;; The cdr of the return value is non-nil when a | 7075 | ;; The second element of the return value is non-nil when a |
| 7057 | ;; `c-typedef-decl-kwds' specifier is found in the declaration. | 7076 | ;; `c-typedef-decl-kwds' specifier is found in the declaration. |
| 7058 | ;; Specifically it is a dotted pair (A . B) where B is t when a | 7077 | ;; Specifically it is a dotted pair (A . B) where B is t when a |
| 7059 | ;; `c-typedef-kwds' ("typedef") is present, and A is t when some | 7078 | ;; `c-typedef-kwds' ("typedef") is present, and A is t when some |
| @@ -7061,6 +7080,10 @@ comment at the start of cc-engine.el for more info." | |||
| 7061 | ;; specifier is present. I.e., (some of) the declared | 7080 | ;; specifier is present. I.e., (some of) the declared |
| 7062 | ;; identifier(s) are types. | 7081 | ;; identifier(s) are types. |
| 7063 | ;; | 7082 | ;; |
| 7083 | ;; The third element of the return value is non-nil when the declaration | ||
| 7084 | ;; parsed might be an expression. The fourth element is the position of | ||
| 7085 | ;; the start of the type identifier. | ||
| 7086 | ;; | ||
| 7064 | ;; If a cast is parsed: | 7087 | ;; If a cast is parsed: |
| 7065 | ;; | 7088 | ;; |
| 7066 | ;; The point is left at the first token after the closing paren of | 7089 | ;; The point is left at the first token after the closing paren of |
| @@ -7161,7 +7184,10 @@ comment at the start of cc-engine.el for more info." | |||
| 7161 | ;; speculatively and should be thrown away if it turns out | 7184 | ;; speculatively and should be thrown away if it turns out |
| 7162 | ;; that it isn't a declaration or cast. | 7185 | ;; that it isn't a declaration or cast. |
| 7163 | (save-rec-type-ids c-record-type-identifiers) | 7186 | (save-rec-type-ids c-record-type-identifiers) |
| 7164 | (save-rec-ref-ids c-record-ref-identifiers)) | 7187 | (save-rec-ref-ids c-record-ref-identifiers) |
| 7188 | ;; Set when we parse a declaration which might also be an expression, | ||
| 7189 | ;; such as "a *b". See CASE 16 and CASE 17. | ||
| 7190 | maybe-expression) | ||
| 7165 | 7191 | ||
| 7166 | (save-excursion | 7192 | (save-excursion |
| 7167 | (goto-char preceding-token-end) | 7193 | (goto-char preceding-token-end) |
| @@ -7799,6 +7825,7 @@ comment at the start of cc-engine.el for more info." | |||
| 7799 | ;; the construct look like a function call) when | 7825 | ;; the construct look like a function call) when |
| 7800 | ;; `at-decl-start' provides additional evidence that we do | 7826 | ;; `at-decl-start' provides additional evidence that we do |
| 7801 | ;; have a declaration. | 7827 | ;; have a declaration. |
| 7828 | (setq maybe-expression t) | ||
| 7802 | (throw 'at-decl-or-cast t)) | 7829 | (throw 'at-decl-or-cast t)) |
| 7803 | 7830 | ||
| 7804 | ;; CASE 17 | 7831 | ;; CASE 17 |
| @@ -7810,6 +7837,7 @@ comment at the start of cc-engine.el for more info." | |||
| 7810 | ;; be an odd expression or it could be a declaration. Treat | 7837 | ;; be an odd expression or it could be a declaration. Treat |
| 7811 | ;; it as a declaration if "a" has been used as a type | 7838 | ;; it as a declaration if "a" has been used as a type |
| 7812 | ;; somewhere else (if it's a known type we won't get here). | 7839 | ;; somewhere else (if it's a known type we won't get here). |
| 7840 | (setq maybe-expression t) | ||
| 7813 | (throw 'at-decl-or-cast t))) | 7841 | (throw 'at-decl-or-cast t))) |
| 7814 | 7842 | ||
| 7815 | ;; CASE 18 | 7843 | ;; CASE 18 |
| @@ -7933,9 +7961,11 @@ comment at the start of cc-engine.el for more info." | |||
| 7933 | (goto-char type-start) | 7961 | (goto-char type-start) |
| 7934 | (c-forward-type)))) | 7962 | (c-forward-type)))) |
| 7935 | 7963 | ||
| 7936 | (cons id-start | 7964 | (list id-start |
| 7937 | (and (or at-type-decl at-typedef) | 7965 | (and (or at-type-decl at-typedef) |
| 7938 | (cons at-type-decl at-typedef)))) | 7966 | (cons at-type-decl at-typedef)) |
| 7967 | maybe-expression | ||
| 7968 | type-start)) | ||
| 7939 | 7969 | ||
| 7940 | (t | 7970 | (t |
| 7941 | ;; False alarm. Restore the recorded ranges. | 7971 | ;; False alarm. Restore the recorded ranges. |
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index e171b20f328..4e83d6df620 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -1336,6 +1336,32 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1336 | (when (> (point) max-type-decl-end) | 1336 | (when (> (point) max-type-decl-end) |
| 1337 | (setq max-type-decl-end (point)))) | 1337 | (setq max-type-decl-end (point)))) |
| 1338 | 1338 | ||
| 1339 | ;; Do we have an expression as the second or third clause of | ||
| 1340 | ;; a "for" paren expression? | ||
| 1341 | (if (save-excursion | ||
| 1342 | (and | ||
| 1343 | (car (cddr decl-or-cast)) ; maybe-expression flag. | ||
| 1344 | (goto-char start-pos) | ||
| 1345 | (c-go-up-list-backward) | ||
| 1346 | (eq (char-after) ?\() | ||
| 1347 | (progn (c-backward-syntactic-ws) | ||
| 1348 | (c-simple-skip-symbol-backward)) | ||
| 1349 | (looking-at c-paren-stmt-key) | ||
| 1350 | (progn (goto-char match-pos) | ||
| 1351 | (while (and (eq (char-before) ?\)) | ||
| 1352 | (c-go-list-backward)) | ||
| 1353 | (c-backward-syntactic-ws)) | ||
| 1354 | (eq (char-before) ?\;)))) | ||
| 1355 | ;; We've got an expression in "for" parens. Remove the | ||
| 1356 | ;; "type" that would spuriously get fontified. | ||
| 1357 | (let ((elt (and (consp c-record-type-identifiers) | ||
| 1358 | (assq (cadr (cddr decl-or-cast)) | ||
| 1359 | c-record-type-identifiers)))) | ||
| 1360 | (when elt | ||
| 1361 | (setq c-record-type-identifiers | ||
| 1362 | (c-delq-from-dotted-list | ||
| 1363 | elt c-record-type-identifiers))) | ||
| 1364 | t) | ||
| 1339 | ;; Back up to the type to fontify the declarator(s). | 1365 | ;; Back up to the type to fontify the declarator(s). |
| 1340 | (goto-char (car decl-or-cast)) | 1366 | (goto-char (car decl-or-cast)) |
| 1341 | 1367 | ||
| @@ -1361,17 +1387,17 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1361 | (c-backward-syntactic-ws) | 1387 | (c-backward-syntactic-ws) |
| 1362 | (unless (bobp) | 1388 | (unless (bobp) |
| 1363 | (c-put-char-property (1- (point)) 'c-type | 1389 | (c-put-char-property (1- (point)) 'c-type |
| 1364 | (if (cdr decl-or-cast) | 1390 | (if (cadr decl-or-cast) |
| 1365 | 'c-decl-type-start | 1391 | 'c-decl-type-start |
| 1366 | 'c-decl-id-start))))) | 1392 | 'c-decl-id-start))))) |
| 1367 | 1393 | ||
| 1368 | (c-font-lock-declarators | 1394 | (c-font-lock-declarators |
| 1369 | (point-max) decl-list (cdr decl-or-cast))) | 1395 | (point-max) decl-list (cadr decl-or-cast))) |
| 1370 | 1396 | ||
| 1371 | ;; A declaration has been successfully identified, so do all the | 1397 | ;; A declaration has been successfully identified, so do all the |
| 1372 | ;; fontification of types and refs that've been recorded. | 1398 | ;; fontification of types and refs that've been recorded. |
| 1373 | (c-fontify-recorded-types-and-refs) | 1399 | (c-fontify-recorded-types-and-refs) |
| 1374 | nil) | 1400 | nil)) |
| 1375 | 1401 | ||
| 1376 | ;; Restore point, since at this point in the code it has been | 1402 | ;; Restore point, since at this point in the code it has been |
| 1377 | ;; left undefined by c-forward-decl-or-cast-1 above. | 1403 | ;; left undefined by c-forward-decl-or-cast-1 above. |