]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-engine.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / progmodes / cc-engine.el
index 39600cf28f87401b7b71d39722e3f9a6875f9cbb..4aff0dc14e094dfa05715b2f18f0bee96527c4da 100644 (file)
@@ -1543,7 +1543,7 @@ comment at the start of cc-engine.el for more info."
 ;;    two newlines with horizontal whitespace between them.
 ;;
 ;;    The reason to include the first following char is to cope with
-;;    "rung positions" that doesn't have any ordinary whitespace.  If
+;;    "rung positions" that don't have any ordinary whitespace.  If
 ;;    `c-is-sws' is put on a token character it does not have
 ;;    `c-in-sws' set simultaneously.  That's the only case when that
 ;;    can occur, and the reason for not extending the `c-in-sws'
@@ -1714,7 +1714,9 @@ comment at the start of cc-engine.el for more info."
     ;; if it's anything that can't start syntactic ws, so we can bail out
     ;; early in the majority of cases when there just are a few ws chars.
     (skip-chars-forward " \t\n\r\f\v")
-    (when (looking-at c-syntactic-ws-start)
+    (when (or (looking-at c-syntactic-ws-start)
+             (and c-opt-cpp-prefix
+                  (looking-at c-noise-macro-name-re)))
 
       (setq rung-end-pos (min (1+ (point)) (point-max)))
       (if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
@@ -1733,6 +1735,10 @@ comment at the start of cc-engine.el for more info."
       (with-silent-modifications
       (while
          (progn
+           ;; In the following while form, we move over a "ladder" and
+           ;; following simple WS each time round the loop, appending the WS
+           ;; onto the ladder, joining adjacent ladders, and terminating when
+           ;; there is no more WS or we reach EOB.
            (while
                (when (and rung-is-marked
                           (get-text-property (point) 'c-in-sws))
@@ -1776,6 +1782,7 @@ comment at the start of cc-engine.el for more info."
                            (setq rung-pos (point)
                                  last-put-in-sws-pos rung-pos)))
 
+           ;; Now move over any comments (x)or a CPP construct.
            (setq simple-ws-end (point))
            (c-forward-comments)
 
@@ -1801,6 +1808,13 @@ comment at the start of cc-engine.el for more info."
              (forward-line 1)
              (setq safe-start t)
              ;; Don't cache at eob in case the buffer is narrowed.
+             (not (eobp)))
+
+            ((and c-opt-cpp-prefix
+                  (looking-at c-noise-macro-name-re))
+             ;; Skip over a noise macro.
+             (goto-char (match-end 1))
+             (setq safe-start t)
              (not (eobp)))))
 
        ;; We've searched over a piece of non-white syntactic ws.  See if this
@@ -1907,8 +1921,11 @@ comment at the start of cc-engine.el for more info."
     (when (and (not (bobp))
               (save-excursion
                 (backward-char)
-                (looking-at c-syntactic-ws-end)))
-
+                (or (looking-at c-syntactic-ws-end)
+                    (and c-opt-cpp-prefix
+                         (looking-at c-symbol-char-key)
+                         (progn (c-beginning-of-current-token)
+                                (looking-at c-noise-macro-name-re))))))
       ;; Try to find a rung position in the simple ws preceding point, so that
       ;; we can get a cache hit even if the last bit of the simple ws has
       ;; changed recently.
@@ -1927,6 +1944,9 @@ comment at the start of cc-engine.el for more info."
       (with-silent-modifications
       (while
          (progn
+           ;; Each time round the next while form, we move back over a ladder
+           ;; and append any simple WS preceding it, if possible joining with
+           ;; the previous ladder.
            (while
                (when (and rung-is-marked
                           (not (bobp))
@@ -2035,6 +2055,15 @@ comment at the start of cc-engine.el for more info."
              ;; narrowed out, and we can't risk marking the simple ws
              ;; at the end of it.
              (goto-char next-rung-pos)
+             t)
+
+            ((and c-opt-cpp-prefix
+                  (save-excursion
+                    (and (< (skip-syntax-backward "w_") 0)
+                         (progn (setq next-rung-pos (point))
+                                (looking-at c-noise-macro-name-re)))))
+             ;; Skipped over a noise macro
+             (goto-char next-rung-pos)
              t)))
 
        ;; We've searched over a piece of non-white syntactic ws.  See if this
@@ -3241,7 +3270,7 @@ comment at the start of cc-engine.el for more info."
   ;; pair element into an open paren element.  Doing that would mean that the
   ;; new open paren wouldn't have the required preceding paren pair element.
   ;;
-  ;; This function is called from c-after-change.
+  ;; This function is called from c-before-change.
 
   ;; The caches of non-literals:
   ;; Note that we use "<=" for the possibility of the second char of a two-char
@@ -3265,7 +3294,7 @@ comment at the start of cc-engine.el for more info."
     ;; below `here'.  To maintain its consistency, we may need to insert a new
     ;; brace pair.
     (let ((here-bol (c-point 'bol here))
-         too-high-pa             ; recorded {/(/[ next above here, or nil.
+         too-high-pa  ; recorded {/(/[ next above or just below here, or nil.
          dropped-cons            ; was the last removed element a brace pair?
          pa)
       ;; The easy bit - knock over-the-top bits off `c-state-cache'.
@@ -3277,7 +3306,7 @@ comment at the start of cc-engine.el for more info."
 
       ;; Do we need to add in an earlier brace pair, having lopped one off?
       (if (and dropped-cons
-              (< too-high-pa (+ here c-state-cache-too-far)))
+              (<= too-high-pa here))
          (c-append-lower-brace-pair-to-state-cache too-high-pa here here-bol))
       (setq c-state-cache-good-pos (or (c-state-cache-after-top-paren)
                                       (c-state-get-min-scan-pos)))))
@@ -3472,6 +3501,9 @@ comment at the start of cc-engine.el for more info."
 (make-variable-buffer-local 'c-parse-state-state)
 (defun c-record-parse-state-state ()
   (setq c-parse-state-point (point))
+  (when (markerp (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)))
+    (move-marker (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)) nil)
+    (move-marker (cdr (assq 'c-state-old-cpp-end c-parse-state-state)) nil))
   (setq c-parse-state-state
        (mapcar
         (lambda (arg)
@@ -4259,8 +4291,7 @@ comment at the start of cc-engine.el for more info."
        (setq safe-pos-list (cdr safe-pos-list)))
       (unless (setq safe-pos (car-safe safe-pos-list))
        (setq safe-pos (max (or (c-safe-position
-                                (point) (or c-state-cache
-                                            (c-parse-state)))
+                                (point) (c-parse-state))
                                0)
                            (point-min))
              safe-pos-list (list safe-pos)))
@@ -4308,107 +4339,108 @@ Non-nil is returned if the point moved, nil otherwise.
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
 
-  (let ((start (point))
-       state-2
-       ;; A list of syntactically relevant positions in descending
-       ;; order.  It's used to avoid scanning repeatedly over
-       ;; potentially large regions with `parse-partial-sexp' to verify
-       ;; each position.  Used in `c-ssb-lit-begin'
-       safe-pos-list
-       ;; The result from `c-beginning-of-macro' at the start position or the
-       ;; start position itself if it isn't within a macro.  Evaluated on
-       ;; demand.
-       start-macro-beg
-       ;; The earliest position after the current one with the same paren
-       ;; level.  Used only when `paren-level' is set.
-       lit-beg
-       (paren-level-pos (point)))
-
-    (while
-       (progn
-         ;; The next loop "tries" to find the end point each time round,
-         ;; loops when it hasn't succeeded.
-         (while
-             (and
-              (let ((pos (point)))
-                (while (and
-                        (< (skip-chars-backward skip-chars limit) 0)
-                        ;; Don't stop inside a literal.
-                        (when (setq lit-beg (c-ssb-lit-begin))
-                          (goto-char lit-beg)
-                          t)))
-                (< (point) pos))
+  (c-self-bind-state-cache
+   (let ((start (point))
+        state-2
+        ;; A list of syntactically relevant positions in descending
+        ;; order.  It's used to avoid scanning repeatedly over
+        ;; potentially large regions with `parse-partial-sexp' to verify
+        ;; each position.  Used in `c-ssb-lit-begin'
+        safe-pos-list
+        ;; The result from `c-beginning-of-macro' at the start position or the
+        ;; start position itself if it isn't within a macro.  Evaluated on
+        ;; demand.
+        start-macro-beg
+        ;; The earliest position after the current one with the same paren
+        ;; level.  Used only when `paren-level' is set.
+        lit-beg
+        (paren-level-pos (point)))
+
+     (while
+        (progn
+          ;; The next loop "tries" to find the end point each time round,
+          ;; loops when it hasn't succeeded.
+          (while
+              (and
+               (let ((pos (point)))
+                 (while (and
+                         (< (skip-chars-backward skip-chars limit) 0)
+                         ;; Don't stop inside a literal.
+                         (when (setq lit-beg (c-ssb-lit-begin))
+                           (goto-char lit-beg)
+                           t)))
+                 (< (point) pos))
+
+               (let ((pos (point)) state-2 pps-end-pos)
 
-              (let ((pos (point)) state-2 pps-end-pos)
+                 (cond
+                  ((and paren-level
+                        (save-excursion
+                          (setq state-2 (parse-partial-sexp
+                                         pos paren-level-pos -1)
+                                pps-end-pos (point))
+                          (/= (car state-2) 0)))
+                   ;; Not at the right level.
+
+                   (if (and (< (car state-2) 0)
+                            ;; We stop above if we go out of a paren.
+                            ;; Now check whether it precedes or is
+                            ;; nested in the starting sexp.
+                            (save-excursion
+                              (setq state-2
+                                    (parse-partial-sexp
+                                     pps-end-pos paren-level-pos
+                                     nil nil state-2))
+                              (< (car state-2) 0)))
+
+                       ;; We've stopped short of the starting position
+                       ;; so the hit was inside a nested list.  Go up
+                       ;; until we are at the right level.
+                       (condition-case nil
+                           (progn
+                             (goto-char (scan-lists pos -1
+                                                    (- (car state-2))))
+                             (setq paren-level-pos (point))
+                             (if (and limit (>= limit paren-level-pos))
+                                 (progn
+                                   (goto-char limit)
+                                   nil)
+                               t))
+                         (error
+                          (goto-char (or limit (point-min)))
+                          nil))
+
+                     ;; The hit was outside the list at the start
+                     ;; position.  Go to the start of the list and exit.
+                     (goto-char (1+ (elt state-2 1)))
+                     nil))
+
+                  ((c-beginning-of-macro limit)
+                   ;; Inside a macro.
+                   (if (< (point)
+                          (or start-macro-beg
+                              (setq start-macro-beg
+                                    (save-excursion
+                                      (goto-char start)
+                                      (c-beginning-of-macro limit)
+                                      (point)))))
+                       t
+
+                     ;; It's inside the same macro we started in so it's
+                     ;; a relevant match.
+                     (goto-char pos)
+                     nil))))))
 
-                (cond
-                 ((and paren-level
-                       (save-excursion
-                         (setq state-2 (parse-partial-sexp
-                                        pos paren-level-pos -1)
-                               pps-end-pos (point))
-                         (/= (car state-2) 0)))
-                  ;; Not at the right level.
-
-                  (if (and (< (car state-2) 0)
-                           ;; We stop above if we go out of a paren.
-                           ;; Now check whether it precedes or is
-                           ;; nested in the starting sexp.
-                           (save-excursion
-                             (setq state-2
-                                   (parse-partial-sexp
-                                    pps-end-pos paren-level-pos
-                                    nil nil state-2))
-                             (< (car state-2) 0)))
-
-                      ;; We've stopped short of the starting position
-                      ;; so the hit was inside a nested list.  Go up
-                      ;; until we are at the right level.
-                      (condition-case nil
-                          (progn
-                            (goto-char (scan-lists pos -1
-                                                   (- (car state-2))))
-                            (setq paren-level-pos (point))
-                            (if (and limit (>= limit paren-level-pos))
-                                (progn
-                                  (goto-char limit)
-                                  nil)
-                              t))
-                        (error
-                         (goto-char (or limit (point-min)))
-                         nil))
-
-                    ;; The hit was outside the list at the start
-                    ;; position.  Go to the start of the list and exit.
-                    (goto-char (1+ (elt state-2 1)))
-                    nil))
-
-                 ((c-beginning-of-macro limit)
-                  ;; Inside a macro.
-                  (if (< (point)
-                         (or start-macro-beg
-                             (setq start-macro-beg
-                                   (save-excursion
-                                     (goto-char start)
-                                     (c-beginning-of-macro limit)
-                                     (point)))))
-                      t
-
-                    ;; It's inside the same macro we started in so it's
-                    ;; a relevant match.
-                    (goto-char pos)
-                    nil))))))
-
-         (> (point)
-            (progn
-              ;; Skip syntactic ws afterwards so that we don't stop at the
-              ;; end of a comment if `skip-chars' is something like "^/".
-              (c-backward-syntactic-ws)
-              (point)))))
+          (> (point)
+             (progn
+               ;; Skip syntactic ws afterwards so that we don't stop at the
+               ;; end of a comment if `skip-chars' is something like "^/".
+               (c-backward-syntactic-ws)
+               (point)))))
 
-    ;; We might want to extend this with more useful return values in
-    ;; the future.
-    (/= (point) start)))
+     ;; We might want to extend this with more useful return values in
+     ;; the future.
+     (/= (point) start))))
 
 ;; The following is an alternative implementation of
 ;; `c-syntactic-skip-backward' that uses backward movement to keep
@@ -5807,12 +5839,16 @@ comment at the start of cc-engine.el for more info."
                               `(c-forward-type)
                             `(c-forward-name)))
                nil
-             (and (looking-at c-keywords-regexp)
-                  (c-forward-keyword-clause 1))))
-     (when (memq res '(t known found prefix))
-       ,(when (eq type 'ref)
-         `(when c-record-type-identifiers
-            (c-record-ref-id c-last-identifier-range)))
+             (cond ((looking-at c-keywords-regexp)
+                    (c-forward-keyword-clause 1))
+                   ((and c-opt-cpp-prefix
+                         (looking-at c-noise-macro-with-parens-name-re))
+                    (c-forward-noise-clause)))))
+     (when (memq res '(t known found prefix maybe))
+       (when c-record-type-identifiers
+        ,(if (eq type 'type)
+             `(c-record-type-id c-last-identifier-range)
+           `(c-record-ref-id c-last-identifier-range)))
        t)))
 
 (defmacro c-forward-id-comma-list (type update-safe-pos)
@@ -5830,6 +5866,17 @@ comment at the start of cc-engine.el for more info."
                 (c-forward-syntactic-ws)
                 (c-forward-keyword-prefixed-id ,type)))))
 
+(defun c-forward-noise-clause ()
+  ;; Point is at a c-noise-macro-with-parens-names macro identifier.  Go
+  ;; forward over this name, any parenthesis expression which follows it, and
+  ;; any syntactic WS, ending up at the next token.  If there is an unbalanced
+  ;; paren expression, leave point at it.  Always Return t.
+  (c-forward-token-2)
+  (if (and (eq (char-after) ?\()
+          (c-go-list-forward))
+      (c-forward-syntactic-ws))
+  t)
+
 (defun c-forward-keyword-clause (match)
   ;; Submatch MATCH in the current match data is assumed to surround a
   ;; token.  If it's a keyword, move over it and any immediately
@@ -6041,7 +6088,7 @@ comment at the start of cc-engine.el for more info."
 
                      (when (or (looking-at "extends")
                                (looking-at "super"))
-                       (forward-word)
+                       (forward-word-strictly)
                        (c-forward-syntactic-ws)
                        (let ((c-promote-possible-types t)
                              (c-record-found-types t))
@@ -6056,7 +6103,10 @@ comment at the start of cc-engine.el for more info."
                   ;; Stop on ',', '|', '&', '+' and '-' to catch
                   ;; common binary operators that could be between
                   ;; two comparison expressions "a<b" and "c>d".
-                  "[<;{},|+&-]\\|[>)]"
+                  ;; 2016-02-11: C++11 templates can now contain arithmetic
+                  ;; expressions, so template detection in C++ is now less
+                  ;; robust than it was.
+                  c-<>-notable-chars-re
                   nil t t))
 
                (cond
@@ -6064,7 +6114,9 @@ comment at the start of cc-engine.el for more info."
                  ;; Either an operator starting with '>' or the end of
                  ;; the angle bracket arglist.
 
-                 (if (looking-at c->-op-without->-cont-regexp)
+                 (if (save-excursion
+                       (c-backward-token-2)
+                       (looking-at c-multichar->-op-not->>-regexp))
                      (progn
                        (goto-char (match-end 0))
                        t)              ; Continue the loop.
@@ -6134,6 +6186,11 @@ comment at the start of cc-engine.el for more info."
                      )))
                  t)                    ; carry on looping.
 
+                ((and
+                  (eq (char-before) ?\()
+                  (c-go-up-list-forward)
+                  (eq (char-before) ?\))))
+
                 ((and (not c-restricted-<>-arglists)
                       (or (and (eq (char-before) ?&)
                                (not (eq (char-after) ?&)))
@@ -6358,13 +6415,15 @@ comment at the start of cc-engine.el for more info."
                    (eq (char-after) ?<))
               ;; Maybe an angle bracket arglist.
               (when (let ((c-record-type-identifiers t)
-                          (c-record-found-types t))
+                          (c-record-found-types t)
+                          (c-last-identifier-range))
                       (c-forward-<>-arglist nil))
 
-                (c-add-type start (1+ pos))
                 (c-forward-syntactic-ws)
-                (setq pos (point)
-                      c-last-identifier-range nil)
+                (unless (eq (char-after) ?\()
+                  (setq c-last-identifier-range nil)
+                  (c-add-type start (1+ pos)))
+                (setq pos (point))
 
                 (if (and c-opt-identifier-concat-key
                          (looking-at c-opt-identifier-concat-key))
@@ -6378,7 +6437,8 @@ comment at the start of cc-engine.el for more info."
                       (c-forward-syntactic-ws)
                       t)
 
-                  (when (and c-record-type-identifiers id-start)
+                  (when (and c-record-type-identifiers id-start
+                             (not (eq (char-after) ?\()))
                     (c-record-type-id (cons id-start id-end)))
                   (setq res 'template)
                   nil)))
@@ -6450,6 +6510,14 @@ comment at the start of cc-engine.el for more info."
                                     ; "typedef".
       (goto-char (match-end 1))
       (c-forward-syntactic-ws)
+
+      (while (cond
+             ((looking-at c-decl-hangon-key)
+              (c-forward-keyword-clause 1))
+             ((and c-opt-cpp-prefix
+                   (looking-at c-noise-macro-with-parens-name-re))
+              (c-forward-noise-clause))))
+
       (setq pos (point))
 
       (setq name-res (c-forward-name))
@@ -6552,9 +6620,18 @@ comment at the start of cc-engine.el for more info."
                           ;; It's an identifier that might be a type.
                           'maybe))))
            ((eq name-res 'template)
-            ;; A template is a type.
+            ;; A template is sometimes a type.
             (goto-char id-end)
-            (setq res t))
+            (c-forward-syntactic-ws)
+            (setq res
+                  (if (eq (char-after) ?\()
+                      (if (c-check-type id-start id-end)
+                          ;; It's an identifier that has been used as
+                          ;; a type somewhere else.
+                          'found
+                        ;; It's an identifier that might be a type.
+                        'maybe)
+                    t)))
            (t
             ;; Otherwise it's an operator identifier, which is not a type.
             (goto-char start)
@@ -6739,6 +6816,9 @@ comment at the start of cc-engine.el for more info."
                      (c-backward-syntactic-ws))
                    (c-back-over-list-of-member-inits)
                    (and (eq (char-before) ?:)
+                        (save-excursion
+                          (c-backward-token-2)
+                          (not (looking-at c-:$-multichar-token-regexp)))
                         (c-just-after-func-arglist-p))))
 
            (while (and (not (and level-plausible
@@ -6753,6 +6833,9 @@ comment at the start of cc-engine.el for more info."
                      (c-backward-syntactic-ws)
                      (c-back-over-list-of-member-inits)
                      (and (eq (char-before) ?:)
+                          (save-excursion
+                            (c-backward-token-2)
+                            (not (looking-at c-:$-multichar-token-regexp)))
                           (c-just-after-func-arglist-p)))))
 
            (and at-top-level level-plausible)))
@@ -6842,31 +6925,39 @@ comment at the start of cc-engine.el for more info."
           ;; of the while.  These are, e.g. "*" in "int *foo" or "(" and
           ;; "*" in "int (*foo) (void)" (Note similar code in
           ;; `c-forward-decl-or-cast-1'.)
-          (while (and (looking-at c-type-decl-prefix-key)
-                      (if (and (c-major-mode-is 'c++-mode)
-                               (match-beginning 3))
-                          ;; If the third submatch matches in C++ then
-                          ;; we're looking at an identifier that's a
-                          ;; prefix only if it specifies a member pointer.
-                          (progn
-                            (setq id-start (point))
-                            (c-forward-name)
-                            (if (looking-at "\\(::\\)")
-                                ;; We only check for a trailing "::" and
-                                ;; let the "*" that should follow be
-                                ;; matched in the next round.
-                                t
-                              ;; It turned out to be the real identifier,
-                              ;; so flag that and stop.
-                              (setq got-identifier t)
-                              nil))
-                        t))
-            (if (eq (char-after) ?\()
-                (progn
-                  (setq paren-depth (1+ paren-depth))
-                  (forward-char))
-              (goto-char (match-end 1)))
-            (c-forward-syntactic-ws))
+             (while
+                 (cond
+                  ((looking-at c-decl-hangon-key)
+                   (c-forward-keyword-clause 1))
+                  ((and c-opt-cpp-prefix
+                        (looking-at c-noise-macro-with-parens-name-re))
+                   (c-forward-noise-clause))
+                  ((and (looking-at c-type-decl-prefix-key)
+                        (if (and (c-major-mode-is 'c++-mode)
+                                 (match-beginning 3))
+                            ;; If the third submatch matches in C++ then
+                            ;; we're looking at an identifier that's a
+                            ;; prefix only if it specifies a member pointer.
+                            (progn
+                              (setq id-start (point))
+                              (c-forward-name)
+                              (if (looking-at "\\(::\\)")
+                                  ;; We only check for a trailing "::" and
+                                  ;; let the "*" that should follow be
+                                  ;; matched in the next round.
+                                  t
+                                ;; It turned out to be the real identifier,
+                                ;; so flag that and stop.
+                                (setq got-identifier t)
+                                nil))
+                          t))
+                   (if (eq (char-after) ?\()
+                       (progn
+                         (setq paren-depth (1+ paren-depth))
+                         (forward-char))
+                     (goto-char (match-end 1)))
+                   (c-forward-syntactic-ws)
+                   t)))
 
           ;; If we haven't passed the identifier already, do it now.
           (unless got-identifier
@@ -6891,9 +6982,13 @@ comment at the start of cc-engine.el for more info."
 
         ;; Skip over any trailing bit, such as "__attribute__".
         (progn
-          (when (looking-at c-decl-hangon-key)
-            (c-forward-keyword-clause 1))
-          (<= (point) limit))
+             (while (cond
+                     ((looking-at c-decl-hangon-key)
+                      (c-forward-keyword-clause 1))
+                     ((and c-opt-cpp-prefix
+                           (looking-at c-noise-macro-with-parens-name-re))
+                      (c-forward-noise-clause))))
+             (<= (point) limit))
 
         ;; Search syntactically to the end of the declarator (";",
         ;; ",", a closing paren, eob etc) or to the beginning of an
@@ -7072,18 +7167,25 @@ comment at the start of cc-engine.el for more info."
     ;; macros like __INLINE__, so we recognize both types and known
     ;; specifiers after them too.
     (while
-       (let* ((start (point)) kwd-sym kwd-clause-end found-type)
+       (let* ((start (point)) kwd-sym kwd-clause-end found-type noise-start)
 
+         (cond
          ;; Look for a specifier keyword clause.
-         (when (or (looking-at c-prefix-spec-kwds-re) ;FIXME!!! includes auto
-                   (and (c-major-mode-is 'java-mode)
-                        (looking-at "@[A-Za-z0-9]+")))
-           (if (save-match-data (looking-at c-typedef-key))
-               (setq at-typedef t))
+          ((or (looking-at c-prefix-spec-kwds-re)
+               (and (c-major-mode-is 'java-mode)
+                (looking-at "@[A-Za-z0-9]+")))
+           (save-match-data
+             (if (looking-at c-typedef-key)
+                 (setq at-typedef t)))
            (setq kwd-sym (c-keyword-sym (match-string 1)))
            (save-excursion
              (c-forward-keyword-clause 1)
              (setq kwd-clause-end (point))))
+          ((and c-opt-cpp-prefix
+                (looking-at c-noise-macro-with-parens-name-re))
+           (setq noise-start (point))
+           (c-forward-noise-clause)
+           (setq kwd-clause-end (point))))
 
          (when (setq found-type (c-forward-type t)) ; brace-block-too
            ;; Found a known or possible type or a prefix of a known type.
@@ -7121,16 +7223,17 @@ comment at the start of cc-engine.el for more info."
                  backup-at-type-decl nil
                  backup-maybe-typeless nil))
 
-         (if kwd-sym
+         (if (or kwd-sym noise-start)
              (progn
                ;; Handle known specifier keywords and
                ;; `c-decl-hangon-kwds' which can occur after known
                ;; types.
 
-               (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
-                   ;; It's a hang-on keyword that can occur anywhere.
+               (if (or (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
+                       noise-start)
+                   ;; It's a hang-on keyword or noise clause that can occur
+                   ;; anywhere.
                    (progn
-                     (setq at-decl-or-cast t)
                      (if at-type
                          ;; Move the identifier start position if
                          ;; we've passed a type.
@@ -7182,8 +7285,12 @@ comment at the start of cc-engine.el for more info."
       ;; If a known type was found, we still need to skip over any
       ;; hangon keyword clauses after it.  Otherwise it has already
       ;; been done in the loop above.
-      (while (looking-at c-decl-hangon-key)
-       (c-forward-keyword-clause 1))
+      (while
+         (cond ((looking-at c-decl-hangon-key)
+                (c-forward-keyword-clause 1))
+               ((and c-opt-cpp-prefix
+                     (looking-at c-noise-macro-with-parens-name-re))
+                (c-forward-noise-clause))))
       (setq id-start (point)))
 
      ((eq at-type 'prefix)
@@ -8950,6 +9057,12 @@ comment at the start of cc-engine.el for more info."
           t)
          ((looking-at c-after-brace-list-key) t)
          ((looking-at c-brace-list-key) nil)
+         ((eq (char-after) ?\()
+          (and (eq (c-backward-token-2) 0)
+               (or (looking-at c-decl-hangon-key)
+                   (and c-opt-cpp-prefix
+                        (looking-at c-noise-macro-with-parens-name-re)))))
+
          ((and c-recognize-<>-arglists
                (eq (char-after) ?<)
                (looking-at "\\s("))
@@ -10210,9 +10323,12 @@ comment at the start of cc-engine.el for more info."
           ;; CASE 5A.3: brace list open
           ((save-excursion
              (c-beginning-of-decl-1 lim)
-             (while (looking-at c-specifier-key)
-               (goto-char (match-end 1))
-               (c-forward-syntactic-ws indent-point))
+             (while (cond
+                     ((looking-at c-specifier-key)
+                      (c-forward-keyword-clause 1))
+                     ((and c-opt-cpp-prefix
+                           (looking-at c-noise-macro-with-parens-name-re))
+                      (c-forward-noise-clause))))
              (setq placeholder (c-point 'boi))
              (or (consp special-brace-list)
                  (and (or (save-excursion
@@ -10264,9 +10380,12 @@ comment at the start of cc-engine.el for more info."
           (t
            (save-excursion
              (c-beginning-of-decl-1 lim)
-             (while (looking-at c-specifier-key)
-               (goto-char (match-end 1))
-               (c-forward-syntactic-ws indent-point))
+             (while (cond
+                     ((looking-at c-specifier-key)
+                      (c-forward-keyword-clause 1))
+                     ((and c-opt-cpp-prefix
+                           (looking-at c-noise-macro-with-parens-name-re))
+                      (c-forward-noise-clause))))
              (c-add-syntax 'defun-open (c-point 'boi))
              ;; Bogus to use bol here, but it's the legacy.  (Resolved,
              ;; 2007-11-09)
@@ -10897,9 +11016,12 @@ comment at the start of cc-engine.el for more info."
            (c-beginning-of-statement-1
             (c-safe-position (1- containing-sexp) paren-state))
            (c-forward-token-2 0)
-           (while (looking-at c-specifier-key)
-             (goto-char (match-end 1))
-             (c-forward-syntactic-ws))
+           (while (cond
+                   ((looking-at c-specifier-key)
+                    (c-forward-keyword-clause 1))
+                   ((and c-opt-cpp-prefix
+                         (looking-at c-noise-macro-with-parens-name-re))
+                    (c-forward-noise-clause))))
            (c-add-syntax 'brace-list-open (c-point 'boi))))
 
         ;; CASE 9B: brace-list-close brace