Ensure C++ initializer lists don't get fontified.

* lisp/progmodes/cc-cmds.el (c-block-comment-flag): Move declaration to solve
compiler warning.

* lisp/progmodes/cc-fonts.el (c-get-fontification-context): Add an extra
clause to handle C++ member initialization lists.
(c-font-lock-single-decl): New function, extracted from
c-font-lock-declarations.
(c-font-lock-declarations): Call c-font-lock-single-decl in place of inline
code.
(c-font-lock-cut-off-declarators): Make more rigorous by calling
c-get-fontification-context, c-forward-decl-or-cast-1, and
c-font-lock-single-decl in place of rather approximate code.
This commit is contained in:
Alan Mackenzie 2017-06-16 11:26:59 +00:00
parent cc6a66b9a1
commit 8c21f8fab9
2 changed files with 108 additions and 79 deletions

View file

@ -251,6 +251,11 @@ With universal argument, inserts the analysis as a comment on that line."
;; Minor mode functions.
;; `c-block-comment-flag' gets initialized to the current mode's default in
;; c-basic-common-init.
(defvar c-block-comment-flag nil)
(make-variable-buffer-local 'c-block-comment-flag)
(defun c-update-modeline ()
(let ((fmt (format "/%s%s%s%s%s"
(if c-block-comment-flag "*" "/")
@ -360,11 +365,6 @@ left out."
(electric-indent-local-mode (if c-electric-flag 1 0)))
(c-keep-region-active))
;; `c-block-comment-flag' gets initialized to the current mode's default in
;; c-basic-common-init.
(defvar c-block-comment-flag nil)
(make-variable-buffer-local 'c-block-comment-flag)
(defun c-toggle-comment-style (&optional arg)
"Toggle the comment style between block and line comments.
Optional numeric ARG, if supplied, switches to block comment

View file

@ -1214,6 +1214,12 @@ casts and declarations are fontified. Used on level 2 and higher."
(and (zerop (c-backward-token-2 2))
(looking-at c-arithmetic-op-regexp))))
(cons nil nil))
;; In a C++ member initialization list.
((and (eq (char-before match-pos) ?,)
(c-major-mode-is 'c++-mode)
(save-excursion (c-back-over-member-initializers)))
(c-put-char-property (1- match-pos) 'c-type 'c-not-decl)
(cons 'not-decl nil))
;; At start of a declaration inside a declaration paren.
((save-excursion
(and (memq (char-before match-pos) '(?\( ?\,))
@ -1235,6 +1241,85 @@ casts and declarations are fontified. Used on level 2 and higher."
(cons 'decl nil))
(t (cons 'arglist t)))))
(defun c-font-lock-single-decl (limit decl-or-cast match-pos context toplev)
;; Try to fontify a single declaration, together with all its declarators.
;; Return nil if we're successful, non-nil if we fail. POINT should be
;; positioned at the start of the putative declaration before calling.
;; POINT is left undefined by this function.
;;
;; LIMIT sets a maximum position we'll fontify out to.
;; DECL-OR-CAST has the form of a result from `c-forward-decl-or-cast-1',
;; and must indicate a declaration (i.e. not be nil or 'cast).
;; MATCH-POS is the position after the last symbol before the decl.
;; CONTEXT is the context of the current decl., as determined by
;; c-get-fontification-context.
;; TOPLEV is non-nil if the decl. is at the top level (i.e. outside any
;; braces, or directly inside a class, namespace, etc.)
;; 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.
(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))
(let ((decl-list
(if (not (memq context '(nil top)))
;; Should normally not fontify a list of
;; declarators inside an arglist, but the first
;; argument in the ';' separated list of a "for"
;; statement is an exception.
(when (eq (char-before match-pos) ?\()
(save-excursion
(goto-char (1- match-pos))
(c-backward-syntactic-ws)
(and (c-simple-skip-symbol-backward)
(looking-at c-paren-stmt-key))))
t)))
;; Fix the `c-decl-id-start' or `c-decl-type-start' property
;; before the first declarator if it's a list.
;; `c-font-lock-declarators' handles the rest.
(when decl-list
(save-excursion
(c-backward-syntactic-ws)
(unless (bobp)
(c-put-char-property (1- (point)) 'c-type
(if (cadr decl-or-cast)
'c-decl-type-start
'c-decl-id-start)))))
(c-font-lock-declarators
(min limit (point-max)) decl-list
(cadr decl-or-cast) (not toplev)))
;; 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))
(defun c-font-lock-declarations (limit)
;; Fontify all the declarations, casts and labels from the point to LIMIT.
;; Assumes that strings and comments have been fontified already.
@ -1436,70 +1521,9 @@ casts and declarations are fontified. Used on level 2 and higher."
(setq max-type-decl-end-before-token (point)))
(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))
(let ((decl-list
(if (not (memq context '(nil top)))
;; Should normally not fontify a list of
;; declarators inside an arglist, but the first
;; argument in the ';' separated list of a "for"
;; statement is an exception.
(when (eq (char-before match-pos) ?\()
(save-excursion
(goto-char (1- match-pos))
(c-backward-syntactic-ws)
(and (c-simple-skip-symbol-backward)
(looking-at c-paren-stmt-key))))
t)))
;; Fix the `c-decl-id-start' or `c-decl-type-start' property
;; before the first declarator if it's a list.
;; `c-font-lock-declarators' handles the rest.
(when decl-list
(save-excursion
(c-backward-syntactic-ws)
(unless (bobp)
(c-put-char-property (1- (point)) 'c-type
(if (cadr decl-or-cast)
'c-decl-type-start
'c-decl-id-start)))))
(c-font-lock-declarators
(min limit (point-max)) decl-list
(cadr decl-or-cast) (not toplev)))
;; 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))
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast match-pos
context toplev))
(t t))))
@ -1584,8 +1608,8 @@ casts and declarations are fontified. Used on level 2 and higher."
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; fontification".
(let ((decl-search-lim (c-determine-limit 1000))
paren-state bod-res is-typedef encl-pos
(here (point))
paren-state encl-pos token-end context decl-or-cast
start-pos top-level c-restricted-<>-arglists
c-recognize-knr-p) ; Strictly speaking, bogus, but it
; speeds up lisp.h tremendously.
(save-excursion
@ -1599,22 +1623,27 @@ casts and declarations are fontified. Used on level 2 and higher."
(c-syntactic-skip-backward "^;{}" decl-search-lim t))
(when (or (bobp)
(memq (char-before) '(?\; ?{ ?})))
(setq token-end (point))
(c-forward-syntactic-ws)
;; We're now putatively at the declaration.
(setq start-pos (point))
(setq paren-state (c-parse-state))
;; At top level or inside a "{"?
(if (or (not (setq encl-pos
(c-most-enclosing-brace paren-state)))
(eq (char-after encl-pos) ?\{))
(progn
(when (looking-at c-typedef-key) ; "typedef"
(setq is-typedef t)
(goto-char (match-end 0))
(c-forward-syntactic-ws))
;; At a real declaration?
(if (memq (c-forward-type t) '(t known found decltype))
(c-font-lock-declarators
limit t is-typedef (not (c-bs-at-toplevel-p here)))))))))
(setq top-level (c-at-toplevel-p))
(let ((got-context (c-get-fontification-context
token-end nil top-level)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
(setq decl-or-cast
(c-forward-decl-or-cast-1 token-end context nil))
(when (consp decl-or-cast)
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast token-end
context top-level)))))))
nil))
(defun c-font-lock-enclosing-decls (limit)