]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-engine.el
Update copyright year to 2015
[gnu-emacs] / lisp / progmodes / cc-engine.el
index 9a2531d1e9933b731b54a4a1426d9c21e99703da..328e0f79a1c7907759111456aa194a010b332883 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-engine.el --- core syntax guessing engine for CC mode -*- coding: utf-8 -*-
 
-;; Copyright (C) 1985, 1987, 1992-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2015 Free Software Foundation, Inc.
 
 ;; Authors:    2001- Alan Mackenzie
 ;;             1998- Martin Stjernholm
     (setq c-macro-cache-start-pos beg
          c-macro-cache-syntactic nil))))
 
+(defun c-macro-is-genuine-p ()
+  ;; Check that the ostensible CPP construct at point is a real one.  In
+  ;; particular, if point is on the first line of a narrowed buffer, make sure
+  ;; that the "#" isn't, say, the second character of a "##" operator.  Return
+  ;; t when the macro is real, nil otherwise.
+  (let ((here (point)))
+    (beginning-of-line)
+    (prog1
+       (if (and (eq (point) (point-min))
+                (/= (point) 1))
+           (save-restriction
+             (widen)
+             (beginning-of-line)
+             (and (looking-at c-anchored-cpp-prefix)
+                  (eq (match-beginning 1) here)))
+         t)
+      (goto-char here))))
+
 (defun c-beginning-of-macro (&optional lim)
   "Go to the beginning of a preprocessor directive.
 Leave point at the beginning of the directive and return t if in one,
@@ -279,7 +297,8 @@ comment at the start of cc-engine.el for more info."
            (forward-line -1))
          (back-to-indentation)
          (if (and (<= (point) here)
-                  (looking-at c-opt-cpp-start))
+                  (looking-at c-opt-cpp-start)
+                  (c-macro-is-genuine-p))
              (progn
                (setq c-macro-cache (cons (point) nil)
                      c-macro-cache-start-pos here)
@@ -515,7 +534,7 @@ comment at the start of cc-engine.el for more info."
     (while (progn
             (when (eq (get-text-property (point) 'c-type) value)
               (c-clear-char-property (point) 'c-type))
-            (goto-char (next-single-property-change (point) 'c-type nil to))
+            (goto-char (c-next-single-property-change (point) 'c-type nil to))
             (< (point) to)))))
 
 \f
@@ -1704,7 +1723,7 @@ comment at the start of cc-engine.el for more info."
          ;; the cases when the marked rung is complete.
          ;; (`next-single-property-change' is certain to move at least one
          ;; step forward.)
-         (setq rung-pos (1- (next-single-property-change
+         (setq rung-pos (1- (c-next-single-property-change
                              rung-is-marked 'c-is-sws nil rung-end-pos)))
        ;; Got no marked rung here.  Since the simple ws might have started
        ;; inside a line comment or cpp directive we must set `rung-pos' as
@@ -1720,7 +1739,7 @@ comment at the start of cc-engine.el for more info."
 
                  ;; The following search is the main reason that `c-in-sws'
                  ;; and `c-is-sws' aren't combined to one property.
-                 (goto-char (next-single-property-change
+                 (goto-char (c-next-single-property-change
                              (point) 'c-in-sws nil (point-max)))
                  (unless (get-text-property (point) 'c-is-sws)
                    ;; If the `c-in-sws' region extended past the last
@@ -1842,7 +1861,7 @@ comment at the start of cc-engine.el for more info."
          ;; possible since we can't be in the ending ws of a line comment or
          ;; cpp directive now.
          (if (setq rung-is-marked next-rung-is-marked)
-             (setq rung-pos (1- (next-single-property-change
+             (setq rung-pos (1- (c-next-single-property-change
                                  rung-is-marked 'c-is-sws nil rung-end-pos)))
            (setq rung-pos next-rung-pos))
          (setq safe-start t)))
@@ -1920,7 +1939,7 @@ comment at the start of cc-engine.el for more info."
                  (unless (get-text-property (point) 'c-is-sws)
                    ;; If the `c-in-sws' region extended past the first
                    ;; `c-is-sws' char we have to go forward a bit.
-                   (goto-char (next-single-property-change
+                   (goto-char (c-next-single-property-change
                                (point) 'c-is-sws)))
 
                  (c-debug-sws-msg
@@ -2221,8 +2240,7 @@ comment at the start of cc-engine.el for more info."
        ((and (not not-in-delimiter)    ; inside a comment starter
             (not (bobp))
             (progn (backward-char)
-                   (and (not (and (memq 'category-properties c-emacs-features)
-                                  (looking-at "\\s!")))
+                   (and (not (looking-at "\\s!"))
                         (looking-at c-comment-start-regexp))))
        (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
              co-st (point))
@@ -2529,7 +2547,7 @@ comment at the start of cc-engine.el for more info."
        (setq pos here+)
        (c-safe
          (while
-             (setq ren+1 (scan-lists pos 1 1)) ; might signal
+             (setq ren+1 (c-sc-scan-lists pos 1 1)) ; might signal
            (setq lonely-rens (cons ren+1 lonely-rens)
                  pos ren+1)))))
 
@@ -2541,7 +2559,7 @@ comment at the start of cc-engine.el for more info."
       (c-safe
        (while
            (and lonely-rens            ; actual values aren't used.
-                (setq pa (scan-lists pos -1 1)))
+                (setq pa (c-sc-scan-lists pos -1 1)))
          (setq pos pa)
          (setq lonely-rens (cdr lonely-rens)))))
     pos))
@@ -2697,8 +2715,8 @@ comment at the start of cc-engine.el for more info."
              (progn
                (c-safe
                  (while
-                     (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; might signal
-                          (setq bra (scan-lists ce -1 1)) ; back past (/[/{; might signal
+                     (and (setq ce (c-sc-scan-lists bra -1 -1)) ; back past )/]/}; might signal
+                          (setq bra (c-sc-scan-lists ce -1 1)) ; back past (/[/{; might signal
                           (or (> bra here) ;(> ce here)
                               (and
                                (< ce here)
@@ -2750,7 +2768,7 @@ comment at the start of cc-engine.el for more info."
                     (not (c-beginning-of-macro))))
          (setq c-state-cache
                (cons (cons (1- bra+1)
-                           (scan-lists bra+1 1 1))
+                           (c-sc-scan-lists bra+1 1 1))
                      (if (consp (car c-state-cache))
                          (cdr c-state-cache)
                        c-state-cache)))
@@ -2800,9 +2818,9 @@ comment at the start of cc-engine.el for more info."
              ;; are no more b/b/p's to scan.
              (c-safe
                (while t
-                 (setq pa+1 (scan-lists ren+1 1 -1) ; Into (/{/[; might signal
+                 (setq pa+1 (c-sc-scan-lists ren+1 1 -1) ; Into (/{/[; might signal
                        paren+1s (cons pa+1 paren+1s))
-                 (setq ren+1 (scan-lists pa+1 1 1)) ; Out of )/}/]; might signal
+                 (setq ren+1 (c-sc-scan-lists pa+1 1 1)) ; Out of )/}/]; might signal
                  (if (and (eq (char-before pa+1) ?{)) ; Check for a macro later.
                      (setq bra+1 pa+1))
                  (setcar paren+1s ren+1)))
@@ -2826,7 +2844,7 @@ comment at the start of cc-engine.el for more info."
                ;; finished - we just need to check for having found an
                ;; unmatched )/}/], which we ignore.  Such a )/}/] can't be in a
                ;; macro, due the action of `c-neutralize-syntax-in-CPP'.
-               (c-safe (setq ren+1 (scan-lists ren+1 1 1)))))) ; acts as loop control.
+               (c-safe (setq ren+1 (c-sc-scan-lists ren+1 1 1)))))) ; acts as loop control.
 
        ;; Record the final, innermost, brace-pair if there is one.
        (c-state-push-any-brace-pair bra+1 macro-start-or-here)
@@ -2929,7 +2947,7 @@ comment at the start of cc-engine.el for more info."
        ;; The next loop jumps forward out of a nested level of parens each
        ;; time round; the corresponding elements in `c-state-cache' are
        ;; removed.  `pos' is just after the brace-pair or the open paren at
-       ;; (car c-state-cache).  There can be no open parens/braces/brackets
+       ;; (car c-state-cache).  There can be no open parens/braces/brackets
        ;; between `start-point'/`start-point-actual-macro-start' and HERE,
        ;; due to the interface spec to this function.
        (setq pos (if (and start-point-actual-macro-end
@@ -2953,7 +2971,7 @@ comment at the start of cc-engine.el for more info."
 
          ;; Scan!
          (setq pps-state
-               (parse-partial-sexp
+               (c-sc-parse-partial-sexp
                 (point) (if (< (point) pps-point) pps-point here)
                 target-depth
                 nil pps-state))
@@ -2984,9 +3002,10 @@ comment at the start of cc-engine.el for more info."
             )))
 
        (if (< (point) pps-point)
-           (setq pps-state (parse-partial-sexp (point) pps-point
-                                               nil nil ; TARGETDEPTH, STOPBEFORE
-                                               pps-state)))
+           (setq pps-state (c-sc-parse-partial-sexp
+                            (point) pps-point
+                            nil nil ; TARGETDEPTH, STOPBEFORE
+                            pps-state)))
 
        ;; If the last paren pair we moved out of was actually a brace pair,
        ;; insert it into `c-state-cache'.
@@ -3107,12 +3126,15 @@ comment at the start of cc-engine.el for more info."
        (save-restriction
          (narrow-to-region here-bol (point-max))
          (setq pos here-lit-start)
-         (c-safe (while (setq pa (scan-lists pos -1 1))
+         (c-safe (while (setq pa (c-sc-scan-lists pos -1 1))
                    (setq pos pa))))    ; might signal
        nil))                           ; for the cond
 
-     ((setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
-       ;; CASE 3: After a }/)/] before `here''s BOL.
+     ((save-restriction
+        (narrow-to-region too-far-back (point-max))
+        (setq ren (c-safe (c-sc-scan-lists pos -1 -1))))
+
+      ;; CASE 3: After a }/)/] before `here''s BOL.
       (list (1+ ren) (and dropped-cons pos) nil)) ; Return value
 
      (t
@@ -3334,15 +3356,19 @@ comment at the start of cc-engine.el for more info."
   ;; of all parens in preprocessor constructs, except for any such construct
   ;; containing point.  We can then call `c-invalidate-state-cache-1' without
   ;; worrying further about macros and template delimiters.
-  (c-with-<->-as-parens-suppressed
-   (if (and c-state-old-cpp-beg
-           (< c-state-old-cpp-beg here))
-       (c-with-all-but-one-cpps-commented-out
-       c-state-old-cpp-beg
-       (min c-state-old-cpp-end here)
-       (c-invalidate-state-cache-1 here))
-     (c-with-cpps-commented-out
-      (c-invalidate-state-cache-1 here)))))
+  (if (eval-when-compile (memq 'category-properties c-emacs-features))
+      ;; Emacs
+      (c-with-<->-as-parens-suppressed
+       (if (and c-state-old-cpp-beg
+               (< c-state-old-cpp-beg here))
+          (c-with-all-but-one-cpps-commented-out
+           c-state-old-cpp-beg
+           (min c-state-old-cpp-end here)
+           (c-invalidate-state-cache-1 here))
+        (c-with-cpps-commented-out
+         (c-invalidate-state-cache-1 here))))
+    ;; XEmacs
+    (c-invalidate-state-cache-1 here)))
 
 (defmacro c-state-maybe-marker (place marker)
   ;; If PLACE is non-nil, return a marker marking it, otherwise nil.
@@ -3370,13 +3396,17 @@ comment at the start of cc-engine.el for more info."
     ;; FIXME!!! Put in a `condition-case' here to protect the integrity of the
     ;; subsystem.
     (prog1
-       (c-with-<->-as-parens-suppressed
-        (if (and here-cpp-beg (> here-cpp-end here-cpp-beg))
-            (c-with-all-but-one-cpps-commented-out
-             here-cpp-beg here-cpp-end
-             (c-parse-state-1))
-          (c-with-cpps-commented-out
-           (c-parse-state-1))))
+       (if (eval-when-compile (memq 'category-properties c-emacs-features))
+           ;; Emacs
+           (c-with-<->-as-parens-suppressed
+            (if (and here-cpp-beg (> here-cpp-end here-cpp-beg))
+                (c-with-all-but-one-cpps-commented-out
+                 here-cpp-beg here-cpp-end
+                 (c-parse-state-1))
+              (c-with-cpps-commented-out
+               (c-parse-state-1))))
+         ;; XEmacs
+         (c-parse-state-1))
       (setq c-state-old-cpp-beg
            (c-state-maybe-marker here-cpp-beg c-state-old-cpp-beg-marker)
            c-state-old-cpp-end
@@ -3399,9 +3429,9 @@ comment at the start of cc-engine.el for more info."
         (lambda (arg)
           (let ((val (symbol-value arg)))
             (cons arg
-                  (if (consp val)
-                      (copy-tree val)
-                    val))))
+                  (cond ((consp val) (copy-tree val))
+                        ((markerp val) (copy-marker val))
+                        (t val)))))
         '(c-state-cache
           c-state-cache-good-pos
           c-state-nonlit-pos-cache
@@ -3421,7 +3451,11 @@ comment at the start of cc-engine.el for more info."
    (concat "(setq "
     (mapconcat
      (lambda (arg)
-       (format "%s %s%s" (car arg) (if (atom (cdr arg)) "" "'") (cdr arg)))
+       (format "%s %s%s" (car arg)
+              (if (atom (cdr arg)) "" "'")
+              (if (markerp (cdr arg))
+                  (format "(copy-marker %s)" (marker-position (cdr arg)))
+                (cdr arg))))
      c-parse-state-state "  ")
     ")")))
 
@@ -4765,7 +4799,7 @@ comment at the start of cc-engine.el for more info."
      (unless cfd-prop-match
        (save-excursion
         (while (progn
-                 (goto-char (next-single-property-change
+                 (goto-char (c-next-single-property-change
                              (point) 'c-type nil cfd-limit))
                  (and (< (point) cfd-limit)
                       (not (eq (c-get-char-property (1- (point)) 'c-type)
@@ -4805,7 +4839,7 @@ comment at the start of cc-engine.el for more info."
               ;; Pseudo match inside a comment or string literal.  Skip out
               ;; of comments and string literals.
               (while (progn
-                       (goto-char (next-single-property-change
+                       (goto-char (c-next-single-property-change
                                    (point) 'face nil cfd-limit))
                        (and (< (point) cfd-limit)
                             (c-got-face-at (point) c-literal-faces))))
@@ -4994,7 +5028,7 @@ comment at the start of cc-engine.el for more info."
         (save-excursion
           (goto-char cfd-start-pos)
           (while (progn
-                   (goto-char (next-single-property-change
+                   (goto-char (c-next-single-property-change
                                (point) 'face nil cfd-limit))
                    (and (< (point) cfd-limit)
                         (c-got-face-at (point) c-literal-faces))))
@@ -5414,8 +5448,8 @@ comment at the start of cc-engine.el for more info."
        (c-go-list-forward))
       (when (equal (c-get-char-property (1- (point)) 'syntax-table)
                   c->-as-paren-syntax) ; should always be true.
-       (c-clear-char-property (1- (point)) 'category))
-      (c-clear-char-property pos 'category))))
+       (c-unmark-<->-as-paren (1- (point))))
+      (c-unmark-<->-as-paren pos))))
 
 (defun c-clear->-pair-props (&optional pos)
   ;; POS (default point) is at a > character.  If it is marked with
@@ -5431,8 +5465,8 @@ comment at the start of cc-engine.el for more info."
        (c-go-up-list-backward))
       (when (equal (c-get-char-property (point) 'syntax-table)
                        c-<-as-paren-syntax) ; should always be true.
-       (c-clear-char-property (point) 'category))
-      (c-clear-char-property pos 'category))))
+       (c-unmark-<->-as-paren (point)))
+      (c-unmark-<->-as-paren pos))))
 
 (defun c-clear-<>-pair-props (&optional pos)
   ;; POS (default point) is at a < or > character.  If it has an
@@ -5521,9 +5555,10 @@ comment at the start of cc-engine.el for more info."
       (c-syntactic-skip-backward "^;{}" (c-determine-limit 512))
       (setq new-beg (point))
 
-      ;; Remove the syntax-table properties from each pertinent <...> pair.
-      ;; Firsly, the ones with the < before beg and > after beg.
-      (while (c-search-forward-char-property 'category 'c-<-as-paren-syntax beg)
+      ;; Remove the syntax-table/category properties from each pertinent <...>
+      ;; pair.  Firsly, the ones with the < before beg and > after beg.
+      (while
+         (c-search-forward-char-property 'syntax-table c-<-as-paren-syntax beg)
        (if (c-clear-<-pair-props-if-match-after beg (1- (point)))
            (setq need-new-beg t)))
 
@@ -5534,7 +5569,7 @@ comment at the start of cc-engine.el for more info."
 
       ;; Remove syntax-table properties from the remaining pertinent <...>
       ;; pairs, those with a > after end and < before end.
-      (while (c-search-backward-char-property 'category 'c->-as-paren-syntax end)
+      (while (c-search-backward-char-property 'syntax-table c->-as-paren-syntax end)
        (if (c-clear->-pair-props-if-match-before end)
            (setq need-new-end t)))
 
@@ -5916,32 +5951,31 @@ comment at the start of cc-engine.el for more info."
        (while (and
                (progn
                  (c-forward-syntactic-ws)
-                 (let ((orig-record-found-types c-record-found-types))
-                   (when (or (and c-record-type-identifiers all-types)
-                             (c-major-mode-is 'java-mode))
-                     ;; All encountered identifiers are types, so set the
-                     ;; promote flag and parse the type.
-                     (progn
-                       (c-forward-syntactic-ws)
-                       (if (looking-at "\\?")
-                           (forward-char)
-                         (when (looking-at c-identifier-start)
-                           (let ((c-promote-possible-types t)
-                                 (c-record-found-types t))
-                             (c-forward-type))))
-
-                       (c-forward-syntactic-ws)
-
-                       (when (or (looking-at "extends")
-                                 (looking-at "super"))
-                         (forward-word)
-                         (c-forward-syntactic-ws)
+                 (when (or (and c-record-type-identifiers all-types)
+                           (c-major-mode-is 'java-mode))
+                   ;; All encountered identifiers are types, so set the
+                   ;; promote flag and parse the type.
+                   (progn
+                     (c-forward-syntactic-ws)
+                     (if (looking-at "\\?")
+                         (forward-char)
+                       (when (looking-at c-identifier-start)
                          (let ((c-promote-possible-types t)
                                (c-record-found-types t))
-                           (c-forward-type)
-                           (c-forward-syntactic-ws))))))
+                           (c-forward-type))))
+
+                     (c-forward-syntactic-ws)
 
-                 (setq pos (point))    ; e.g. first token inside the '<'
+                     (when (or (looking-at "extends")
+                               (looking-at "super"))
+                       (forward-word)
+                       (c-forward-syntactic-ws)
+                       (let ((c-promote-possible-types t)
+                             (c-record-found-types t))
+                         (c-forward-type)
+                         (c-forward-syntactic-ws)))))
+
+                 (setq pos (point))    ; e.g. first token inside the '<'
 
                  ;; Note: These regexps exploit the match order in \| so
                  ;; that "<>" is matched by "<" rather than "[^>:-]>".
@@ -6031,7 +6065,7 @@ comment at the start of cc-engine.el for more info."
                       (or (and (eq (char-before) ?&)
                                (not (eq (char-after) ?&)))
                           (eq (char-before) ?,)))
-                 ;; Just another argument.      Record the position.  The
+                 ;; Just another argument.  Record the position.  The
                  ;; type check stuff that made us stop at it is at
                  ;; the top of the loop.
                  (setq arg-start-pos (cons (point) arg-start-pos)))
@@ -6454,13 +6488,14 @@ comment at the start of cc-engine.el for more info."
             (setq res nil)))))
 
     (when res
-      ;; Skip trailing type modifiers. If any are found we know it's
+      ;; Skip trailing type modifiers.  If any are found we know it's
       ;; a type.
       (when c-opt-type-modifier-key
        (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
          (goto-char (match-end 1))
          (c-forward-syntactic-ws)
          (setq res t)))
+
       ;; Step over any type suffix operator.  Do not let the existence
       ;; of these alter the classification of the found type, since
       ;; these operators typically are allowed in normal expressions
@@ -6542,7 +6577,7 @@ comment at the start of cc-engine.el for more info."
        (progn (c-forward-syntactic-ws) t)
        (if (looking-at "(")
           (c-go-list-forward)
-         t)))
+        t)))
 
 (defmacro c-pull-open-brace (ps)
   ;; Pull the next open brace from PS (which has the form of paren-state),
@@ -6553,6 +6588,36 @@ comment at the start of cc-engine.el for more info."
      (prog1 (car ,ps)
        (setq ,ps (cdr ,ps)))))
 
+(defun c-back-over-member-initializer-braces ()
+  ;; Point is just after a closing brace/parenthesis.  Try to parse this as a
+  ;; C++ member initializer list, going back to just after the introducing ":"
+  ;; and returning t.  Otherwise return nil, leaving point unchanged.
+  (let ((here (point)) res)
+    (setq res
+       (catch 'done
+         (when (not (c-go-list-backward))
+           (throw 'done nil))
+         (c-backward-syntactic-ws)
+         (when (not (c-simple-skip-symbol-backward))
+           (throw 'done nil))
+         (c-backward-syntactic-ws)
+
+         (while (eq (char-before) ?,)
+           (backward-char)
+           (c-backward-syntactic-ws)
+           (when (not (memq (char-before) '(?\) ?})))
+             (throw 'done nil))
+           (when (not (c-go-list-backward))
+             (throw 'done nil))
+           (c-backward-syntactic-ws)
+           (when (not (c-simple-skip-symbol-backward))
+             (throw 'done nil))
+           (c-backward-syntactic-ws))
+
+         (eq (char-before) ?:)))
+    (or res (goto-char here))
+    res))
+
 (defun c-back-over-member-initializers ()
   ;; Test whether we are in a C++ member initializer list, and if so, go back
   ;; to the introducing ":", returning the position of the opening paren of
@@ -7129,7 +7194,7 @@ comment at the start of cc-engine.el for more info."
 
         ;; Now we've collected info about various characteristics of
         ;; the construct we're looking at.  Below follows a decision
-        ;; tree based on that.  It's ordered to check more certain
+        ;; tree based on that.  It's ordered to check more certain
         ;; signs before less certain ones.
 
         (if got-identifier
@@ -7215,7 +7280,7 @@ comment at the start of cc-engine.el for more info."
                    at-decl-end
                    (cond
                     ((eq context 'decl)
-                     ;; Inside an arglist that contains declarations.  If K&R
+                     ;; Inside an arglist that contains declarations.  If K&R
                      ;; style declarations and parenthesis style initializers
                      ;; aren't allowed then the single identifier must be a
                      ;; type, else we require that it's known or found
@@ -7248,7 +7313,7 @@ comment at the start of cc-engine.el for more info."
                                    c-after-suffixed-type-maybe-decl-key))))))
               ;; Got an empty paren pair and a preceding type that probably
               ;; really is the identifier.  Shift the type backwards to make
-              ;; the last one the identifier.  This is analogous to the
+              ;; the last one the identifier.  This is analogous to the
               ;; "backtracking" done inside the `c-type-decl-suffix-key' loop
               ;; above.
               ;;
@@ -7256,7 +7321,7 @@ comment at the start of cc-engine.el for more info."
               ;; "backtracking" code, do not shift backward if we're not
               ;; looking at either `c-after-suffixed-type-decl-key' or "[;,]".
               ;; Since there's no preceding type, the shift would mean that
-              ;; the declaration is typeless.  But if the regexp doesn't match
+              ;; the declaration is typeless.  But if the regexp doesn't match
               ;; then we will simply fall through in the tests below and not
               ;; recognize it at all, so it's better to try it as an abstract
               ;; declarator instead.
@@ -7395,7 +7460,7 @@ comment at the start of cc-engine.el for more info."
                          (not got-suffix))
                 ;; Got something like "foo * bar;".  Since we're not inside an
                 ;; arglist it would be a meaningless expression because the
-                ;; result isn't used.  We therefore choose to recognize it as
+                ;; result isn't used.  We therefore choose to recognize it as
                 ;; a declaration.  Do not allow a suffix since it could then
                 ;; be a function call.
                 (throw 'at-decl-or-cast t))
@@ -7406,7 +7471,7 @@ comment at the start of cc-engine.el for more info."
                          (eq at-type 'found)
                          (not (eq context 'arglist)))
                 ;; Got something like "a (*b) (c);" or "a (b) = c;".  It could
-                ;; be an odd expression or it could be a declaration.  Treat
+                ;; be an odd expression or it could be a declaration.  Treat
                 ;; it as a declaration if "a" has been used as a type
                 ;; somewhere else (if it's a known type we won't get here).
                 (throw 'at-decl-or-cast t)))
@@ -7417,7 +7482,7 @@ comment at the start of cc-engine.el for more info."
                          (and (eq context 'decl)
                               (not c-recognize-paren-inits)
                               (or got-parens got-suffix))))
-            ;; Got a type followed by an abstract declarator.  If `got-prefix'
+            ;; Got a type followed by an abstract declarator.  If `got-prefix'
             ;; is set it's something like "a *" without anything after it.  If
             ;; `got-parens' or `got-suffix' is set it's "a()", "a[]", "a()[]",
             ;; or similar, which we accept only if the context rules out
@@ -8087,7 +8152,7 @@ comment at the start of cc-engine.el for more info."
                            (c-forward-token-2))
                          (eq (char-after) ?\))))))
 
-                   ;; ...Yes.  We've identified the function's argument list.
+                   ;; ...Yes.  We've identified the function's argument list.
                    (throw 'knr
                           (progn (goto-char after-rparen)
                                  (c-forward-syntactic-ws)
@@ -8414,10 +8479,7 @@ comment at the start of cc-engine.el for more info."
     (when (and c-recognize-<>-arglists
               (eq (char-before) ?>))
       ;; Could be at the end of a template arglist.
-      (let ((c-parse-and-markup-<>-arglists t)
-           (c-disallow-comma-in-<>-arglists
-            (and containing-sexp
-                 (not (eq (char-after containing-sexp) ?{)))))
+      (let ((c-parse-and-markup-<>-arglists t))
        (while (and
                (c-backward-<>-arglist nil limit)
                (progn
@@ -8441,31 +8503,44 @@ comment at the start of cc-engine.el for more info."
           (cond
            ((c-syntactic-re-search-forward c-decl-block-key open-brace t t t)
             (goto-char (setq kwd-start (match-beginning 0)))
-            (or
-
-             ;; Found a keyword that can't be a type?
-             (match-beginning 1)
-
-             ;; Can be a type too, in which case it's the return type of a
-             ;; function (under the assumption that no declaration level
-             ;; block construct starts with a type).
-             (not (c-forward-type))
-
-             ;; Jumped over a type, but it could be a declaration keyword
-             ;; followed by the declared identifier that we've jumped over
-             ;; instead (e.g. in "class Foo {").  If it indeed is a type
-             ;; then we should be at the declarator now, so check for a
-             ;; valid declarator start.
-             ;;
-             ;; Note: This doesn't cope with the case when a declared
-             ;; identifier is followed by e.g. '(' in a language where '('
-             ;; also might be part of a declarator expression.  Currently
-             ;; there's no such language.
-             (not (or (looking-at c-symbol-start)
-                      (looking-at c-type-decl-prefix-key)))))
+            (and
+             ;; Exclude cases where we matched what would ordinarily
+             ;; be a block declaration keyword, except where it's not
+             ;; legal because it's part of a "compound keyword" like
+             ;; "enum class".  Of course, if c-after-brace-list-key
+             ;; is nil, we can skip the test.
+             (or (equal c-after-brace-list-key "\\<\\>")
+                 (save-match-data
+                   (save-excursion
+                     (not
+                      (and
+                       (looking-at c-after-brace-list-key)
+                       (= (c-backward-token-2 1 t) 0)
+                       (looking-at c-brace-list-key))))))
+             (or
+              ;; Found a keyword that can't be a type?
+              (match-beginning 1)
+
+              ;; Can be a type too, in which case it's the return type of a
+              ;; function (under the assumption that no declaration level
+              ;; block construct starts with a type).
+              (not (c-forward-type))
+
+              ;; Jumped over a type, but it could be a declaration keyword
+              ;; followed by the declared identifier that we've jumped over
+              ;; instead (e.g. in "class Foo {").  If it indeed is a type
+              ;; then we should be at the declarator now, so check for a
+              ;; valid declarator start.
+              ;;
+              ;; Note: This doesn't cope with the case when a declared
+              ;; identifier is followed by e.g. '(' in a language where '('
+              ;; also might be part of a declarator expression.  Currently
+              ;; there's no such language.
+              (not (or (looking-at c-symbol-start)
+                       (looking-at c-type-decl-prefix-key))))))
 
            ;; In Pike a list of modifiers may be followed by a brace
-           ;; to make them apply to many identifiers.  Note that the
+           ;; to make them apply to many identifiers.  Note that the
            ;; match data will be empty on return in this case.
            ((and (c-major-mode-is 'pike-mode)
                  (progn
@@ -8567,11 +8642,44 @@ comment at the start of cc-engine.el for more info."
                      (not (looking-at "=")))))
       b-pos)))
 
+(defun c-backward-colon-prefixed-type ()
+  ;; We're at the token after what might be a type prefixed with a colon.  Try
+  ;; moving backward over this type and the colon.  On success, return t and
+  ;; leave point before colon; on failure, leave point unchanged.  Will clobber
+  ;; match data.
+  (let ((here (point))
+       (colon-pos nil))
+    (save-excursion
+      (while
+         (and (eql (c-backward-token-2) 0)
+              (or (not (looking-at "\\s)"))
+                  (c-go-up-list-backward))
+              (cond
+               ((eql (char-after) ?:)
+                (setq colon-pos (point))
+                (forward-char)
+                (c-forward-syntactic-ws)
+                (or (and (c-forward-type)
+                         (progn (c-forward-syntactic-ws)
+                                (eq (point) here)))
+                    (setq colon-pos nil))
+                nil)
+               ((eql (char-after) ?\()
+                t)
+               ((looking-at c-symbol-key)
+                t)
+               (t nil)))))
+    (when colon-pos
+      (goto-char colon-pos)
+      t)))
+
 (defun c-backward-over-enum-header ()
   ;; We're at a "{".  Move back to the enum-like keyword that starts this
   ;; declaration and return t, otherwise don't move and return nil.
   (let ((here (point))
        up-sexp-pos before-identifier)
+    (when c-recognize-post-brace-list-type-p
+      (c-backward-colon-prefixed-type))
     (while
        (and
         (eq (c-backward-token-2) 0)
@@ -8582,10 +8690,11 @@ comment at the start of cc-engine.el for more info."
                (not before-identifier))
           (setq before-identifier t))
          ((and before-identifier
-               (or (eq (char-after) ?,)
+               (or (eql (char-after) ?,)
                    (looking-at c-postfix-decl-spec-key)))
           (setq before-identifier nil)
           t)
+         ((looking-at c-after-brace-list-key) t)
          ((looking-at c-brace-list-key) nil)
          ((and c-recognize-<>-arglists
                (eq (char-after) ?<)
@@ -8633,7 +8742,7 @@ comment at the start of cc-engine.el for more info."
         (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
+            ;; 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)
@@ -9395,15 +9504,15 @@ comment at the start of cc-engine.el for more info."
      ;;annotations.
      ((and (c-major-mode-is 'java-mode)
           (setq placeholder (point))
-            (c-beginning-of-statement-1)
-            (progn
-              (while (and (c-forward-annotation)
-                          (< (point) placeholder))
-                (c-forward-syntactic-ws))
-              t)
-            (prog1
-                (>= (point) placeholder)
-              (goto-char placeholder)))
+          (c-beginning-of-statement-1)
+          (progn
+            (while (and (c-forward-annotation)
+                        (< (point) placeholder))
+              (c-forward-syntactic-ws))
+            t)
+          (prog1
+              (>= (point) placeholder)
+            (goto-char placeholder)))
        (c-beginning-of-statement-1 containing-sexp)
        (c-add-syntax 'annotation-var-cont (point)))
 
@@ -9454,7 +9563,7 @@ comment at the start of cc-engine.el for more info."
        ((indent-point (point))
         (case-fold-search nil)
         open-paren-in-column-0-is-defun-start
-        ;; A whole ugly bunch of various temporary variables.  Have
+        ;; A whole ugly bunch of various temporary variables.  Have
         ;; to declare them here since it's not possible to declare
         ;; a variable with only the scope of a cond test and the
         ;; following result clauses, and most of this function is a
@@ -9509,22 +9618,26 @@ comment at the start of cc-engine.el for more info."
                                       (c-keyword-sym (match-string 1)))))
 
       ;; Init some position variables.
-      (if c-state-cache
+      (if paren-state
          (progn
            (setq containing-sexp (car paren-state)
                  paren-state (cdr paren-state))
            (if (consp containing-sexp)
-               (progn
-                 (setq lim (cdr containing-sexp))
-                 (if (cdr c-state-cache)
-                     ;; Ignore balanced paren.  The next entry
-                     ;; can't be another one.
-                     (setq containing-sexp (car (cdr c-state-cache))
-                           paren-state (cdr paren-state))
-                   ;; If there is no surrounding open paren then
-                   ;; put the last balanced pair back on paren-state.
-                   (setq paren-state (cons containing-sexp paren-state)
-                         containing-sexp nil)))
+             (save-excursion
+               (goto-char (cdr containing-sexp))
+               (if (and (c-major-mode-is 'c++-mode)
+                        (c-back-over-member-initializer-braces))
+                     (c-syntactic-skip-backward "^}" nil t))
+               (setq lim (point))
+               (if paren-state
+                   ;; Ignore balanced paren.    The next entry
+                   ;; can't be another one.
+                   (setq containing-sexp (car paren-state)
+                         paren-state (cdr paren-state))
+                 ;; If there is no surrounding open paren then
+                 ;; put the last balanced pair back on paren-state.
+                 (setq paren-state (cons containing-sexp paren-state)
+                       containing-sexp nil)))
              (setq lim (1+ containing-sexp))))
        (setq lim (point-min)))
 
@@ -10366,7 +10479,7 @@ comment at the start of cc-engine.el for more info."
                             paren-state))
 
         ;; CASE 7B: Looking at the opening brace of an
-        ;; in-expression block or brace list.  C.f. cases 4, 16A
+        ;; in-expression block or brace list.  C.f. cases 4, 16A
         ;; and 17E.
         ((and (eq char-after-ip ?{)
               (progn
@@ -10488,7 +10601,7 @@ comment at the start of cc-engine.el for more info."
          )))
 
        ;; CASE 9: we are inside a brace-list
-       ((and (not (c-major-mode-is 'awk-mode)) ; Maybe this isn't needed (ACM, 2002/3/29)
+       ((and (not (c-major-mode-is 'awk-mode))  ; Maybe this isn't needed (ACM, 2002/3/29)
             (setq special-brace-list
                   (or (and c-special-brace-lists ;;;; ALWAYS NIL FOR AWK!!
                            (save-excursion
@@ -10702,9 +10815,9 @@ comment at the start of cc-engine.el for more info."
         ))
 
        ;; CASE 19: line is an expression, not a statement, and is directly
-       ;; contained by a template delimiter.   Most likely, we are in a
+       ;; contained by a template delimiter.  Most likely, we are in a
        ;; template arglist within a statement.  This case is based on CASE
-       ;; 7.   At some point in the future, we may wish to create more
+       ;; 7.  At some point in the future, we may wish to create more
        ;; syntactic symbols such as `template-intro',
        ;; `template-cont-nonempty', etc., and distinguish between them as we
        ;; do for `arglist-intro' etc. (2009-12-07).
@@ -11040,7 +11153,7 @@ Cannot combine absolute offsets %S and %S in `add' method"
   ;;
   ;; This function might do hidden buffer changes.
   (let* ((symbol (c-langelem-sym langelem))
-        (match  (assq symbol c-offsets-alist))
+        (match (assq symbol c-offsets-alist))
         (offset (cdr-safe match)))
     (if match
        (setq offset (c-evaluate-offset offset langelem symbol))
@@ -11111,4 +11224,8 @@ Cannot combine absolute offsets %S and %S in `add' method"
 \f
 (cc-provide 'cc-engine)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-engine.el ends here