aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2016-05-16 11:27:39 +0000
committerAlan Mackenzie2016-05-16 11:27:39 +0000
commit116acebfbd28649b6ccf34e5c9046738d57aa28e (patch)
treebc1bd43469ba4fdbe316d709bdeb4d9e85fe45bf
parent65c8c7cb96c14f9c6accd03cc8851b5a3459049e (diff)
downloademacs-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.el44
-rw-r--r--lisp/progmodes/cc-fonts.el32
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.