]> git.eshelyaron.com Git - emacs.git/commitdiff
Adapt CC Mode for C++11 uniform initialization.
authorAlan Mackenzie <acm@muc.de>
Sun, 21 Aug 2016 16:00:15 +0000 (16:00 +0000)
committerAlan Mackenzie <acm@muc.de>
Sun, 21 Aug 2016 16:00:15 +0000 (16:00 +0000)
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
lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-langs.el
lisp/progmodes/cc-mode.el

index 8e8e4e490b7a93f036726c10f25a1130ee779849..ccdc1b15a6823a0ab4cfa287b3d1638b81d2248c 100644 (file)
 ;;      '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))
index ae18d0a943655f1447a5b885b54f155844f8969a..60b8b6db3cc4acdc26b45b09309c89d218f1e33e 100644 (file)
@@ -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.
index 1d9b8d3f0a4a5e77347069d878c4a8e809447edb..e1ccc7924abcf187b1908cc0438afb90371666ea 100644 (file)
@@ -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
index 694a510677add71202a1b6309da445e783c28e88..5b324d6d24c2c4bf0a479c0ae1bb15b564046de3 100644 (file)
@@ -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))