[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 578d9aa: Adapt CC Mode for C++11 uniform initializa
From: |
Alan Mackenzie |
Subject: |
[Emacs-diffs] master 578d9aa: Adapt CC Mode for C++11 uniform initialization. |
Date: |
Sun, 21 Aug 2016 16:07:25 +0000 (UTC) |
branch: master
commit 578d9aaf82b386c1a0316dde491d297e18e10636
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>
Adapt CC Mode for C++11 uniform initialization.
For fontification, introduce a new "context", 'non-decl, to be used for
brace
lists; also a new value for the property 'c-type, called 'c-not-decl.
* lisp/progmodes/cc-engine.el (c-back-over-compound-identifier): Check that
an ostensible symbol we're going to move over isn't a keyword.
(c-forward-decl-or-cast-1): CASE 1: Where we have two consecutive
identifiers
(hence a declaration), and an unmatched open paren, perform
c-fdoc-shift-type-backwards to recognize the partial construct correctly.
Whilst checking a type decl expression, check for and handle C++11's "copy
initialization", where we have <type>(<constant>). Recognize
<id><id>(... (where the paren is unclosed) as a declaration.
(c-looking-at-or-maybe-in-bracelist): New function, extracted from
c-inside-bracelist-p. Recognize as bracelists "{"s which are preceded by
valid tokens other than "=". Recognize a bracelist when preceded by a
template declaration.
(c-inside-bracelist-p): Call c-looking-at-or-maybe-in-bracelist in place of
much inline code.
(c-looking-at-inexpr-block): Amend so that it won't wrongly recognise an
initialization starting "({" as an in-expression block, by checking for
semicolons, as opposed to commas, separating elements inside it.
(c-guess-continued-construct): (CASE B-2): Recognize a brace-list-open by
calling c-looking-at-or-maybe-in-bracelist rather than checking for a
preceding "=". (CASE B-5): New code to recognize new construct "return {
...}".
(c-guess-basic-syntax): (CASE 5A.3): Additionally recognize a "{" preceded
by
"return", or "{" preceded by <type><identifier> as a bracelist.
* lisp/progmodes/cc-fonts.el (c-font-lock-declarations): Recognize brace
lists, giving them `context' 'non-decl. Pass over elements of one by regexp
search for "," rather than calling c-forward-decl-or-cast-1.
* lisp/progmodes/cc-langs.el (c-return-kwds, c-return-key): New lang
constants/variables to recognize "return".
(c-pre-id-bracelist-key): New lang constant/variable to recognize tokens
which, when preceding an identifier followed by a brace, signify the brace
as
a bracelist.
* lisp/progmodes/cc-mode.el (c-fl-decl-start): When searching outwards for
the start of a "local" declaration, move out from an enclosing brace when
that is the start of a brace list.
---
lisp/progmodes/cc-engine.el | 364 ++++++++++++++++++++++++++++---------------
lisp/progmodes/cc-fonts.el | 267 +++++++++++++++++--------------
lisp/progmodes/cc-langs.el | 17 ++
lisp/progmodes/cc-mode.el | 15 +-
4 files changed, 415 insertions(+), 248 deletions(-)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 8e8e4e4..ccdc1b1 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -130,6 +130,10 @@
;; 'c-decl-type-start is used when the declarators are types,
;; 'c-decl-id-start otherwise.
;;
+;; 'c-not-decl
+;; Put on the brace which introduces a brace list and on the commas
+;; which separate the element within it.
+;;
;; 'c-awk-NL-prop
;; Used in AWK mode to mark the various kinds of newlines. See
;; cc-awk.el.
@@ -7354,10 +7358,10 @@ comment at the start of cc-engine.el for more info."
;; this construct and return t. If the parsing fails, return nil, leaving
;; point unchanged.
(let ((here (point))
- end
- )
- (if (not (c-simple-skip-symbol-backward))
+ end)
+ (if (not (c-on-identifier))
nil
+ (c-simple-skip-symbol-backward)
(while
(progn
(setq end (point))
@@ -7712,6 +7716,8 @@ comment at the start of cc-engine.el for more info."
;; 'arglist Some other type of arglist.
;; nil Some other context or unknown context. Includes
;; within the parens of an if, for, ... construct.
+ ;; 'not-decl This value is never supplied to this function. It
+ ;; would mean we're definitely not in a declaration.
;;
;; LAST-CAST-END is the first token after the closing paren of a
;; preceding cast, or nil if none is known. If
@@ -8019,7 +8025,10 @@ comment at the start of cc-engine.el for more info."
;; arglist paren that gets entered.
c-parse-and-markup-<>-arglists
;; Start of the identifier for which `got-identifier' was set.
- name-start)
+ name-start
+ ;; Position after (innermost) open parenthesis encountered in the
+ ;; prefix operators.
+ after-paren-pos)
(goto-char id-start)
@@ -8030,7 +8039,8 @@ comment at the start of cc-engine.el for more info."
(when (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
- (forward-char)))
+ (forward-char)
+ (setq after-paren-pos (point))))
(while (and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(match-beginning 3))
@@ -8053,7 +8063,8 @@ comment at the start of cc-engine.el for more info."
(if (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
- (forward-char))
+ (forward-char)
+ (setq after-paren-pos (point)))
(unless got-prefix-before-parens
(setq got-prefix-before-parens (= paren-depth 0)))
(setq got-prefix t)
@@ -8062,7 +8073,7 @@ comment at the start of cc-engine.el for more info."
(setq got-parens (> paren-depth 0))
- ;; Skip over an identifier.
+ ;; Try to skip over an identifier.
(or got-identifier
(and (looking-at c-identifier-start)
(setq pos (point))
@@ -8111,7 +8122,15 @@ comment at the start of cc-engine.el for more info."
maybe-typeless
backup-maybe-typeless
(when c-recognize-typeless-decls
- (not context)))
+ (and (not context)
+ ;; Deal with C++11's "copy-initialization"
+ ;; where we have <type>(<constant>), by
+ ;; contraasting with a typeless
+ ;; <name>(<type><parameter>, ...).
+ (save-excursion
+ (goto-char after-paren-pos)
+ (c-forward-syntactic-ws)
+ (c-forward-type)))))
(setq pos (c-up-list-forward (point)))
(eq (char-before pos) ?\)))
(c-fdoc-shift-type-backward)
@@ -8149,11 +8168,15 @@ comment at the start of cc-engine.el for more info."
;; Encountered something inside parens that isn't matched by
;; the `c-type-decl-*' regexps, so it's not a type decl
;; expression. Try to skip out to the same paren depth to
- ;; not confuse the cast check below.
- (c-safe (goto-char (scan-lists (point) 1 paren-depth)))
+ ;; not confuse the cast check below. If we don't manage this and
+ ;; `at-decl-or-cast' is 'ids we might have an expression like
+ ;; "foo bar ({ ..." which is a valid C++11 initialization.
+ (if (and (not (c-safe (goto-char (scan-lists (point) 1
paren-depth))))
+ (eq at-decl-or-cast 'ids))
+ (c-fdoc-shift-type-backward))
;; If we've found a specifier keyword then it's a
;; declaration regardless.
- (throw 'at-decl-or-cast (eq at-decl-or-cast t)))
+ (throw 'at-decl-or-cast (memq at-decl-or-cast '(t ids))))
(setq at-decl-end
(looking-at (cond ((eq context '<>) "[,>]")
@@ -9788,6 +9811,169 @@ comment at the start of cc-engine.el for more info."
(or (looking-at c-brace-list-key)
(progn (goto-char here) nil))))
+(defun c-looking-at-or-maybe-in-bracelist (containing-sexp &optional lim)
+ ;; Point is at an open brace. If this starts a brace list, return the
+ ;; buffer position of the start of the construct which introduces the list.
+ ;; Otherwise, if point might be inside an enclosing brace list, return t.
+ ;; If point is definitely neither at nor in a brace list, return nil.
+ ;;
+ ;; CONTAINING-SEXP is the position of the brace/paren/braacket enclosing
+ ;; POINT, or nil if there is no such position. LIM is a backward search
+ ;; limit.
+ ;;
+ ;; Here, "brace list" does not include the body of an enum.
+ (save-excursion
+ (let ((start (point))
+ (class-key
+ ;; Pike can have class definitions anywhere, so we must
+ ;; check for the class key here.
+ (and (c-major-mode-is 'pike-mode)
+ c-decl-block-key))
+ (braceassignp 'dontknow)
+ bufpos macro-start res after-type-id-pos)
+
+ (setq res (c-backward-token-2 1 t lim))
+ ;; Checks to do only on the first sexp before the brace.
+ ;; Have we a C++ initialisation, without an "="?
+ (if (and (c-major-mode-is 'c++-mode)
+ (cond
+ ((and (not (eq res 0))
+ (c-go-up-list-backward nil lim) ; FIXME!!! Check ; `lim'
2016-07-12.
+ (eq (char-after) ?\())
+ (setq braceassignp 'c++-noassign))
+ ((looking-at c-pre-id-bracelist-key))
+ ((looking-at c-return-key))
+ ((and (looking-at c-symbol-start)
+ (not (looking-at c-keywords-regexp)))
+ (setq after-type-id-pos (point)))
+ (t nil))
+ (save-excursion
+ (cond
+ ((not (eq res 0))
+ (and (c-go-up-list-backward nil lim) ; FIXME!!! Check `lim'
2016-07-12.
+ (eq (char-after) ?\()))
+ ((looking-at c-pre-id-bracelist-key))
+ ((looking-at c-return-key))
+ (t (setq after-type-id-pos (point))
+ nil))))
+ (setq braceassignp 'c++-noassign))
+
+ (when (and c-opt-inexpr-brace-list-key
+ (eq (char-after) ?\[))
+ ;; In Java, an initialization brace list may follow
+ ;; directly after "new Foo[]", so check for a "new"
+ ;; earlier.
+ (while (eq braceassignp 'dontknow)
+ (setq braceassignp
+ (cond ((/= (c-backward-token-2 1 t lim) 0) nil)
+ ((looking-at c-opt-inexpr-brace-list-key) t)
+ ((looking-at "\\sw\\|\\s_\\|[.[]")
+ ;; Carry on looking if this is an
+ ;; identifier (may contain "." in Java)
+ ;; or another "[]" sexp.
+ 'dontknow)
+ (t nil)))))
+
+ ;; Checks to do on all sexps before the brace, up to the
+ ;; beginning of the statement.
+ (while (eq braceassignp 'dontknow)
+ (cond ((eq (char-after) ?\;)
+ (setq braceassignp nil))
+ ((and class-key
+ (looking-at class-key))
+ (setq braceassignp nil))
+ ((eq (char-after) ?=)
+ ;; We've seen a =, but must check earlier tokens so
+ ;; that it isn't something that should be ignored.
+ (setq braceassignp 'maybe)
+ (while (and (eq braceassignp 'maybe)
+ (zerop (c-backward-token-2 1 t lim)))
+ (setq braceassignp
+ (cond
+ ;; Check for operator =
+ ((and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix))
+ nil)
+ ;; Check for `<opchar>= in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (or (eq (char-after) ?`)
+ ;; Special case for Pikes
+ ;; `[]=, since '[' is not in
+ ;; the punctuation class.
+ (and (eq (char-after) ?\[)
+ (eq (char-before) ?`))))
+ nil)
+ ((looking-at "\\s.") 'maybe)
+ ;; make sure we're not in a C++ template
+ ;; argument assignment
+ ((and
+ (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (let ((here (point))
+ (pos< (progn
+ (skip-chars-backward "^<>")
+ (point))))
+ (and (eq (char-before) ?<)
+ (not (c-crosses-statement-barrier-p
+ pos< here))
+ (not (c-in-literal))
+ ))))
+ nil)
+ (t t))))))
+ (if (and (eq braceassignp 'dontknow)
+ (/= (c-backward-token-2 1 t lim) 0))
+ (setq braceassignp nil)))
+
+ (cond
+ (braceassignp
+ ;; We've hit the beginning of the aggregate list.
+ (c-beginning-of-statement-1 containing-sexp)
+ (point))
+ ((and after-type-id-pos
+ (save-excursion
+ (when (eq (char-after) ?\;)
+ (c-forward-token-2 1 t))
+ (setq bufpos (point))
+ (when (looking-at c-opt-<>-sexp-key)
+ (c-forward-token-2)
+ (when (and (eq (char-after) ?<)
+ (c-get-char-property (point) 'syntax-table))
+ (c-go-list-forward nil after-type-id-pos)
+ (c-forward-syntactic-ws)))
+ (and
+ (or (not (looking-at c-class-key))
+ (save-excursion
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (not (eq (point) after-type-id-pos))))
+ (progn
+ (setq res
+ (c-forward-decl-or-cast-1
+ (save-excursion (c-backward-syntactic-ws) (point))
+ nil nil))
+ (and (consp res)
+ (eq (car res) after-type-id-pos))))))
+ bufpos)
+ ((eq (char-after) ?\;)
+ ;; Brace lists can't contain a semicolon, so we're done.
+ ;; (setq containing-sexp nil)
+ nil)
+ ((and (setq macro-start (point))
+ (c-forward-to-cpp-define-body)
+ (eq (point) start))
+ ;; We've a macro whose expansion starts with the '{'.
+ ;; Heuristically, if we have a ';' in it we've not got a
+ ;; brace list, otherwise we have.
+ (let ((macro-end (progn (c-end-of-macro) (point))))
+ (goto-char start)
+ (forward-char)
+ (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t)
+ (eq (char-before) ?\;))
+ nil
+ macro-start)))
+ (t t)) ;; The caller can go up one level.
+ )))
+
(defun c-inside-bracelist-p (containing-sexp paren-state)
;; return the buffer position of the beginning of the brace list
;; statement if we're inside a brace list, otherwise return nil.
@@ -9807,13 +9993,9 @@ comment at the start of cc-engine.el for more info."
(c-backward-over-enum-header))
;; this will pick up array/aggregate init lists, even if they are nested.
(save-excursion
- (let ((class-key
- ;; Pike can have class definitions anywhere, so we must
- ;; check for the class key here.
- (and (c-major-mode-is 'pike-mode)
- c-decl-block-key))
- bufpos braceassignp lim next-containing macro-start)
- (while (and (not bufpos)
+ (let ((bufpos t)
+ lim next-containing)
+ (while (and (eq bufpos t)
containing-sexp)
(when paren-state
(if (consp (car paren-state))
@@ -9823,113 +10005,22 @@ comment at the start of cc-engine.el for more info."
(when paren-state
(setq next-containing (car paren-state)
paren-state (cdr paren-state))))
+
(goto-char containing-sexp)
(if (c-looking-at-inexpr-block next-containing next-containing)
;; We're in an in-expression block of some kind. Do not
;; check nesting. We deliberately set the limit to the
;; containing sexp, so that c-looking-at-inexpr-block
;; doesn't check for an identifier before it.
- (setq containing-sexp nil)
- ;; see if the open brace is preceded by = or [...] in
- ;; this statement, but watch out for operator=
- (setq braceassignp 'dontknow)
- (c-backward-token-2 1 t lim)
- ;; Checks to do only on the first sexp before the brace.
- (when (and c-opt-inexpr-brace-list-key
- (eq (char-after) ?\[))
- ;; In Java, an initialization brace list may follow
- ;; directly after "new Foo[]", so check for a "new"
- ;; earlier.
- (while (eq braceassignp 'dontknow)
- (setq braceassignp
- (cond ((/= (c-backward-token-2 1 t lim) 0) nil)
- ((looking-at c-opt-inexpr-brace-list-key) t)
- ((looking-at "\\sw\\|\\s_\\|[.[]")
- ;; Carry on looking if this is an
- ;; identifier (may contain "." in Java)
- ;; or another "[]" sexp.
- 'dontknow)
- (t nil)))))
- ;; Checks to do on all sexps before the brace, up to the
- ;; beginning of the statement.
- (while (eq braceassignp 'dontknow)
- (cond ((eq (char-after) ?\;)
- (setq braceassignp nil))
- ((and class-key
- (looking-at class-key))
- (setq braceassignp nil))
- ((eq (char-after) ?=)
- ;; We've seen a =, but must check earlier tokens so
- ;; that it isn't something that should be ignored.
- (setq braceassignp 'maybe)
- (while (and (eq braceassignp 'maybe)
- (zerop (c-backward-token-2 1 t lim)))
- (setq braceassignp
- (cond
- ;; Check for operator =
- ((and c-opt-op-identifier-prefix
- (looking-at c-opt-op-identifier-prefix))
- nil)
- ;; Check for `<opchar>= in Pike.
- ((and (c-major-mode-is 'pike-mode)
- (or (eq (char-after) ?`)
- ;; Special case for Pikes
- ;; `[]=, since '[' is not in
- ;; the punctuation class.
- (and (eq (char-after) ?\[)
- (eq (char-before) ?`))))
- nil)
- ((looking-at "\\s.") 'maybe)
- ;; make sure we're not in a C++ template
- ;; argument assignment
- ((and
- (c-major-mode-is 'c++-mode)
- (save-excursion
- (let ((here (point))
- (pos< (progn
- (skip-chars-backward "^<>")
- (point))))
- (and (eq (char-before) ?<)
- (not (c-crosses-statement-barrier-p
- pos< here))
- (not (c-in-literal))
- ))))
- nil)
- (t t))))))
- (if (and (eq braceassignp 'dontknow)
- (/= (c-backward-token-2 1 t lim) 0))
- (setq braceassignp nil)))
- (cond
- (braceassignp
- ;; We've hit the beginning of the aggregate list.
- (c-beginning-of-statement-1
- (c-most-enclosing-brace paren-state))
- (setq bufpos (point)))
- ((eq (char-after) ?\;)
- ;; Brace lists can't contain a semicolon, so we're done.
- (setq containing-sexp nil))
- ((and (setq macro-start (point))
- (c-forward-to-cpp-define-body)
- (eq (point) containing-sexp))
- ;; We've a macro whose expansion starts with the '{'.
- ;; Heuristically, if we have a ';' in it we've not got a
- ;; brace list, otherwise we have.
- (let ((macro-end (progn (c-end-of-macro) (point))))
- (goto-char containing-sexp)
- (forward-char)
- (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t)
- (eq (char-before) ?\;))
- (setq bufpos nil
- containing-sexp nil)
- (setq bufpos macro-start))))
- (t
- ;; Go up one level
+ (setq bufpos nil)
+ (when (or (not (eq (char-after) ?{))
+ (eq (setq bufpos (c-looking-at-or-maybe-in-bracelist
+ next-containing lim))
+ t))
(setq containing-sexp next-containing
lim nil
- next-containing nil)))))
-
- bufpos))
- ))
+ next-containing nil))))
+ (and (numberp bufpos) bufpos)))))
(defun c-looking-at-special-brace-list (&optional lim)
;; If we're looking at the start of a pike-style list, i.e., `({ })',
@@ -10156,7 +10247,19 @@ comment at the start of cc-engine.el for more info."
(and (> (point) (or lim (point-min)))
(c-on-identifier)))
(and c-special-brace-lists
- (c-looking-at-special-brace-list)))
+ (c-looking-at-special-brace-list))
+ (and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (goto-char block-follows)
+ (if (c-go-list-forward)
+ (progn
+ (backward-char)
+ (c-syntactic-skip-backward
+ "^;," block-follows t)
+ (not (eq (char-before) ?\;)))
+ (or (not (c-syntactic-re-search-forward
+ "[;,]" nil t t))
+ (not (eq (char-before) ?\;)))))))
nil
(cons 'inexpr-statement (point)))))
@@ -10565,10 +10668,10 @@ comment at the start of cc-engine.el for more info."
;; CASE B.2: brace-list-open
((or (consp special-brace-list)
- (save-excursion
- (goto-char beg-of-same-or-containing-stmt)
- (c-syntactic-re-search-forward "=\\([^=]\\|$\\)"
- indent-point t t t)))
+ (numberp
+ (c-looking-at-or-maybe-in-bracelist
+ containing-sexp beg-of-same-or-containing-stmt))
+ )
;; The most semantically accurate symbol here is
;; brace-list-open, but we normally report it simply as a
;; statement-cont. The reason is that one normally adjusts
@@ -10601,6 +10704,14 @@ comment at the start of cc-engine.el for more info."
(c-add-stmt-syntax 'defun-open nil t
containing-sexp paren-state))
+ ;; CASE B.5: We have a C++11 "return \n { ..... }" Note that we're
+ ;; not at the "{", currently.
+ ((progn (goto-char indent-point)
+ (backward-sexp)
+ (looking-at c-return-key))
+ (c-add-stmt-syntax 'statement-cont nil t
+ containing-sexp paren-state))
+
;; CASE B.4: Continued statement with block open. The most
;; accurate analysis is perhaps `statement-cont' together with
;; `block-open' but we play DWIM and use `substatement-open'
@@ -11120,7 +11231,14 @@ comment at the start of cc-engine.el for more info."
(looking-at c-opt-inexpr-brace-list-key)
(setq tmpsymbol 'topmost-intro-cont)))
(looking-at "=\\([^=]\\|$\\)"))
- (looking-at c-brace-list-key))
+ (looking-at c-brace-list-key)
+ (looking-at c-return-key)
+ (save-excursion
+ (and (c-forward-type)
+ (looking-at c-identifier-start)
+ (not (looking-at c-keywords-regexp))
+ (c-forward-token-2)
+ (eq (point) (c-point 'boi indent-point)))))
(save-excursion
(while (and (< (point) indent-point)
(zerop (c-forward-token-2 1 t))
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index ae18d0a..60b8b6d 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1166,7 +1166,8 @@ casts and declarations are fontified. Used on level 2
and higher."
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
- (boundp 'parse-sexp-lookup-properties))))
+ (boundp 'parse-sexp-lookup-properties))
+ ))
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
@@ -1204,7 +1205,8 @@ casts and declarations are fontified. Used on level 2
and higher."
(setq start-pos (point))
(when
;; The result of the form below is true when we don't recognize a
- ;; declaration or cast.
+ ;; declaration or cast, and we don't recognise a "non-decl",
+ ;; typically a brace list.
(if (or (and (eq (get-text-property (point) 'face)
'font-lock-keyword-face)
(looking-at c-not-decl-init-keywords))
@@ -1220,7 +1222,7 @@ casts and declarations are fontified. Used on level 2
and higher."
;; (e.g. "for (").
(let ((type (and (> match-pos (point-min))
(c-get-char-property (1- match-pos) 'c-type))))
- (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
+ (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
(setq context nil
c-restricted-<>-arglists nil))
;; A control flow expression or a decltype
@@ -1242,6 +1244,10 @@ casts and declarations are fontified. Used on level 2
and higher."
((eq type 'c-decl-arg-start)
(setq context 'decl
c-restricted-<>-arglists nil))
+ ;; We're inside (probably) a brace list.
+ ((eq type 'c-not-decl)
+ (setq context 'not-decl
+ c-restricted-<>-arglists nil))
;; Inside a C++11 lambda function arglist.
((and (c-major-mode-is 'c++-mode)
(eq (char-before match-pos) ?\()
@@ -1255,7 +1261,20 @@ casts and declarations are fontified. Used on level 2
and higher."
c-restricted-<>-arglists nil)
(c-put-char-property (1- match-pos) 'c-type
'c-decl-arg-start))
-
+ ;; We're inside an brace list.
+ ((and (eq (char-before match-pos) ?{)
+ (save-excursion
+ (goto-char (1- match-pos))
+ (numberp
+ (c-looking-at-or-maybe-in-bracelist nil))))
+ (setq context 'not-decl
+ c-restricted-<>-arglists nil)
+ (c-put-char-property (1- match-pos) 'c-type
+ 'c-not-decl))
+ ;; We're inside an "ordinary" open brace.
+ ((eq (char-before match-pos) ?{)
+ (setq context nil
+ c-restricted-<>-arglists nil))
;; Inside an angle bracket arglist.
((or (eq type 'c-<>-arg-sep)
(eq (char-before match-pos) ?<))
@@ -1301,123 +1320,131 @@ casts and declarations are fontified. Used on level
2 and higher."
(c-forward-syntactic-ws))
;; Now analyze the construct.
- (setq decl-or-cast (c-forward-decl-or-cast-1
- match-pos context last-cast-end))
-
- ;; Ensure that c-<>-arg-sep c-type properties are in place on the
- ;; commas separating the arguments inside template/generic <..>s.
- (when (and (eq (char-before match-pos) ?<)
- (> match-pos max-<>-end))
- (save-excursion
- (goto-char match-pos)
- (c-backward-token-2)
- (if (and
- (eq (char-after) ?<)
- (let ((c-restricted-<>-arglists
- (save-excursion
- (c-backward-token-2)
- (and
- (not (looking-at c-opt-<>-sexp-key))
- (progn (c-backward-syntactic-ws)
- (memq (char-before) '(?\( ?,)))
- (not (eq (c-get-char-property (1- (point))
- 'c-type)
- 'c-decl-arg-start))))))
- (c-forward-<>-arglist nil)))
- (setq max-<>-end (point)))))
-
- (cond
- ((eq decl-or-cast 'cast)
- ;; Save the position after the previous cast so we can feed
- ;; it to `c-forward-decl-or-cast-1' in the next round. That
- ;; helps it discover cast chains like "(a) (b) c".
- (setq last-cast-end (point))
- (c-fontify-recorded-types-and-refs)
- nil)
+ (if (eq context 'not-decl)
+ (progn
+ (setq decl-or-cast nil)
+ (if (c-syntactic-re-search-forward
+ "," (min limit (point-max)) 'at-limit t)
+ (c-put-char-property (1- (point)) 'c-type 'c-not-decl))
+ nil)
+ (setq decl-or-cast
+ (c-forward-decl-or-cast-1
+ match-pos context last-cast-end))
+
+ ;; Ensure that c-<>-arg-sep c-type properties are in place on the
+ ;; commas separating the arguments inside template/generic <..>s.
+ (when (and (eq (char-before match-pos) ?<)
+ (> match-pos max-<>-end))
+ (save-excursion
+ (goto-char match-pos)
+ (c-backward-token-2)
+ (if (and
+ (eq (char-after) ?<)
+ (let ((c-restricted-<>-arglists
+ (save-excursion
+ (c-backward-token-2)
+ (and
+ (not (looking-at c-opt-<>-sexp-key))
+ (progn (c-backward-syntactic-ws)
+ (memq (char-before) '(?\( ?,)))
+ (not (eq (c-get-char-property (1- (point))
+ 'c-type)
+ 'c-decl-arg-start))))))
+ (c-forward-<>-arglist nil)))
+ (setq max-<>-end (point)))))
+
+ (cond
+ ((eq decl-or-cast 'cast)
+ ;; Save the position after the previous cast so we can feed
+ ;; it to `c-forward-decl-or-cast-1' in the next round. That
+ ;; helps it discover cast chains like "(a) (b) c".
+ (setq last-cast-end (point))
+ (c-fontify-recorded-types-and-refs)
+ nil)
+
+ (decl-or-cast
+ ;; We've found a declaration.
+
+ ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
+ ;; under the assumption that we're after the first type decl
+ ;; expression in the declaration now. That's not really true;
+ ;; we could also be after a parenthesized initializer
+ ;; expression in C++, but this is only used as a last resort
+ ;; to slant ambiguous expression/declarations, and overall
+ ;; it's worth the risk to occasionally fontify an expression
+ ;; as a declaration in an initializer expression compared to
+ ;; getting ambiguous things in normal function prototypes
+ ;; fontified as expressions.
+ (if inside-macro
+ (when (> (point) max-type-decl-end-before-token)
+ (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 context
+ ;; 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)))
+
+ ;; 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))
- (decl-or-cast
- ;; We've found a declaration.
-
- ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
- ;; under the assumption that we're after the first type decl
- ;; expression in the declaration now. That's not really true;
- ;; we could also be after a parenthesized initializer
- ;; expression in C++, but this is only used as a last resort
- ;; to slant ambiguous expression/declarations, and overall
- ;; it's worth the risk to occasionally fontify an expression
- ;; as a declaration in an initializer expression compared to
- ;; getting ambiguous things in normal function prototypes
- ;; fontified as expressions.
- (if inside-macro
- (when (> (point) max-type-decl-end-before-token)
- (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 context
- ;; 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)))
-
- ;; 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))
-
- (t t)))
+ (t t))))
;; It was a false alarm. Check if we're in a label (or other
;; construct with `:' except bitfield) instead.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 1d9b8d3..e1ccc79 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1772,6 +1772,16 @@ the appropriate place for that."
"array" "float" "function" "int" "mapping" "mixed" "multiset"
"object" "program" "string" "this_program" "void"))
+(c-lang-defconst c-return-kwds
+ "Keywords which return a value to the calling function."
+ t '("return")
+ idl nil)
+
+(c-lang-defconst c-return-key
+ ;; Adorned regexp matching `c-return-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-return-kwds)))
+(c-lang-defvar c-return-key (c-lang-const c-return-key))
+
(c-lang-defconst c-primitive-type-key
;; An adorned regexp that matches `c-primitive-type-kwds'.
t (c-make-keywords-re t (c-lang-const c-primitive-type-kwds)))
@@ -3150,6 +3160,13 @@ list."
c t)
(c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p))
+(c-lang-defconst c-pre-id-bracelist-key
+ "A regexp matching tokens which, preceding an identifier, signify a
bracelist.
+"
+ t "\\<\\>"
+ c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)")
+(c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key))
+
(c-lang-defconst c-recognize-typeless-decls
"Non-nil means function declarations without return type should be
recognized. That can introduce an ambiguity with parenthesized macro
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 694a510..5b324d6 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1351,10 +1351,10 @@ Note that the style variables are always made local to
the buffer."
(defun c-fl-decl-start (pos)
;; If the beginning of the line containing POS is in the middle of a "local"
- ;; declaration (i.e. one which does not start outside of braces enclosing
- ;; POS, such as a struct), return the beginning of that declaration.
- ;; Otherwise return nil. Note that declarations, in this sense, can be
- ;; nested.
+ ;; declaration, return the beginning of that declaration. Otherwise return
+ ;; nil. Note that declarations, in this sense, can be nested. (A local
+ ;; declaration is one which does not start outside of struct braces (and
+ ;; similar) enclosing POS. Brace list braces here are not "similar".
;;
;; This function is called indirectly from font locking stuff - either from
;; c-after-change (to prepare for after-change font-locking) or from font
@@ -1402,7 +1402,12 @@ Note that the style variables are always made local to
the buffer."
(and (eq (char-before) ?\<)
(eq (c-get-char-property
(1- (point)) 'syntax-table)
- c-<-as-paren-syntax)))))
+ c-<-as-paren-syntax))
+ (and (eq (char-before) ?{)
+ (save-excursion
+ (backward-char)
+ (numberp (c-looking-at-or-maybe-in-bracelist nil))))
+ )))
(not (bobp)))
(backward-char)) ; back over (, [, <.
(when (and capture-opener (< capture-opener new-pos))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 578d9aa: Adapt CC Mode for C++11 uniform initialization.,
Alan Mackenzie <=