mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-25 06:17:34 +00:00
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.
This commit is contained in:
parent
65c8c7cb96
commit
116acebfbd
2 changed files with 66 additions and 10 deletions
|
|
@ -385,6 +385,25 @@ comment at the start of cc-engine.el for more info."
|
|||
|
||||
;;; Basic utility functions.
|
||||
|
||||
(defun c-delq-from-dotted-list (elt dlist)
|
||||
;; If ELT is a member of the (possibly dotted) list DLIST, remove all
|
||||
;; occurrences of it (except for any in the last cdr of DLIST).
|
||||
;;
|
||||
;; Call this as (setq DLIST (c-delq-from-dotted-list ELT DLIST)), as
|
||||
;; sometimes the original structure is changed, sometimes it's not.
|
||||
;;
|
||||
;; This function is needed in Emacs < 24.5, and possibly XEmacs, because
|
||||
;; `delq' throws an error in these versions when given a dotted list.
|
||||
(let ((tail dlist) prev)
|
||||
(while (consp tail)
|
||||
(if (eq (car tail) elt)
|
||||
(if prev
|
||||
(setcdr prev (cdr tail))
|
||||
(setq dlist (cdr dlist)))
|
||||
(setq prev tail))
|
||||
(setq tail (cdr tail)))
|
||||
dlist))
|
||||
|
||||
(defun c-syntactic-content (from to paren-level)
|
||||
;; Return the given region as a string where all syntactic
|
||||
;; 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."
|
|||
;; If a declaration is parsed:
|
||||
;;
|
||||
;; The point is left at the first token after the first complete
|
||||
;; declarator, if there is one. The return value is a cons where
|
||||
;; the car is the position of the first token in the declarator. (See
|
||||
;; below for the cdr.)
|
||||
;; declarator, if there is one. The return value is a list of 4 elements,
|
||||
;; where the first is the position of the first token in the declarator.
|
||||
;; (See below for the other three.)
|
||||
;; Some examples:
|
||||
;;
|
||||
;; void foo (int a, char *b) stuff ...
|
||||
|
|
@ -7053,7 +7072,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;;
|
||||
;;
|
||||
;;
|
||||
;; The cdr of the return value is non-nil when a
|
||||
;; The second element of the return value is non-nil when a
|
||||
;; `c-typedef-decl-kwds' specifier is found in the declaration.
|
||||
;; Specifically it is a dotted pair (A . B) where B is t when a
|
||||
;; `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."
|
|||
;; specifier is present. I.e., (some of) the declared
|
||||
;; identifier(s) are types.
|
||||
;;
|
||||
;; The third element of the return value is non-nil when the declaration
|
||||
;; parsed might be an expression. The fourth element is the position of
|
||||
;; the start of the type identifier.
|
||||
;;
|
||||
;; If a cast is parsed:
|
||||
;;
|
||||
;; 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."
|
|||
;; speculatively and should be thrown away if it turns out
|
||||
;; that it isn't a declaration or cast.
|
||||
(save-rec-type-ids c-record-type-identifiers)
|
||||
(save-rec-ref-ids c-record-ref-identifiers))
|
||||
(save-rec-ref-ids c-record-ref-identifiers)
|
||||
;; Set when we parse a declaration which might also be an expression,
|
||||
;; such as "a *b". See CASE 16 and CASE 17.
|
||||
maybe-expression)
|
||||
|
||||
(save-excursion
|
||||
(goto-char preceding-token-end)
|
||||
|
|
@ -7799,6 +7825,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;; the construct look like a function call) when
|
||||
;; `at-decl-start' provides additional evidence that we do
|
||||
;; have a declaration.
|
||||
(setq maybe-expression t)
|
||||
(throw 'at-decl-or-cast t))
|
||||
|
||||
;; CASE 17
|
||||
|
|
@ -7810,6 +7837,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;; be an odd expression or it could be a declaration. Treat
|
||||
;; it as a declaration if "a" has been used as a type
|
||||
;; somewhere else (if it's a known type we won't get here).
|
||||
(setq maybe-expression t)
|
||||
(throw 'at-decl-or-cast t)))
|
||||
|
||||
;; CASE 18
|
||||
|
|
@ -7933,9 +7961,11 @@ comment at the start of cc-engine.el for more info."
|
|||
(goto-char type-start)
|
||||
(c-forward-type))))
|
||||
|
||||
(cons id-start
|
||||
(list id-start
|
||||
(and (or at-type-decl at-typedef)
|
||||
(cons at-type-decl at-typedef))))
|
||||
(cons at-type-decl at-typedef))
|
||||
maybe-expression
|
||||
type-start))
|
||||
|
||||
(t
|
||||
;; False alarm. Restore the recorded ranges.
|
||||
|
|
|
|||
|
|
@ -1336,6 +1336,32 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(when (> (point) max-type-decl-end)
|
||||
(setq max-type-decl-end (point))))
|
||||
|
||||
;; Do we have an expression as the second or third clause of
|
||||
;; a "for" paren expression?
|
||||
(if (save-excursion
|
||||
(and
|
||||
(car (cddr decl-or-cast)) ; maybe-expression flag.
|
||||
(goto-char start-pos)
|
||||
(c-go-up-list-backward)
|
||||
(eq (char-after) ?\()
|
||||
(progn (c-backward-syntactic-ws)
|
||||
(c-simple-skip-symbol-backward))
|
||||
(looking-at c-paren-stmt-key)
|
||||
(progn (goto-char match-pos)
|
||||
(while (and (eq (char-before) ?\))
|
||||
(c-go-list-backward))
|
||||
(c-backward-syntactic-ws))
|
||||
(eq (char-before) ?\;))))
|
||||
;; We've got an expression in "for" parens. Remove the
|
||||
;; "type" that would spuriously get fontified.
|
||||
(let ((elt (and (consp c-record-type-identifiers)
|
||||
(assq (cadr (cddr decl-or-cast))
|
||||
c-record-type-identifiers))))
|
||||
(when elt
|
||||
(setq c-record-type-identifiers
|
||||
(c-delq-from-dotted-list
|
||||
elt c-record-type-identifiers)))
|
||||
t)
|
||||
;; Back up to the type to fontify the declarator(s).
|
||||
(goto-char (car decl-or-cast))
|
||||
|
||||
|
|
@ -1361,17 +1387,17 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(c-backward-syntactic-ws)
|
||||
(unless (bobp)
|
||||
(c-put-char-property (1- (point)) 'c-type
|
||||
(if (cdr decl-or-cast)
|
||||
(if (cadr decl-or-cast)
|
||||
'c-decl-type-start
|
||||
'c-decl-id-start)))))
|
||||
|
||||
(c-font-lock-declarators
|
||||
(point-max) decl-list (cdr decl-or-cast)))
|
||||
(point-max) decl-list (cadr decl-or-cast)))
|
||||
|
||||
;; A declaration has been successfully identified, so do all the
|
||||
;; fontification of types and refs that've been recorded.
|
||||
(c-fontify-recorded-types-and-refs)
|
||||
nil)
|
||||
nil))
|
||||
|
||||
;; Restore point, since at this point in the code it has been
|
||||
;; left undefined by c-forward-decl-or-cast-1 above.
|
||||
|
|
|
|||
Loading…
Reference in a new issue