]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-engine.el
Merge changes from emacs-23 branch
[gnu-emacs] / lisp / progmodes / cc-engine.el
index f1e6bf98ecea1769bfa3a7ee45a9ae42d2a5dd31..f90d29bf00946cb1da028ddcdfccc59d35fa291e 100644 (file)
@@ -1,8 +1,6 @@
 ;;; cc-engine.el --- core syntax guessing engine for CC mode
 
-;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2011  Free Software Foundation, Inc.
 
 ;; Authors:    2001- Alan Mackenzie
 ;;             1998- Martin Stjernholm
@@ -12,8 +10,8 @@
 ;;             1985 Richard M. Stallman
 ;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    22-Apr-1997 (split from cc-mode.el)
-;; Version:    See cc-mode.el
-;; Keywords:   c languages oop
+;; Keywords:   c languages
+;; Package:    cc-mode
 
 ;; This file is part of GNU Emacs.
 
@@ -447,7 +445,7 @@ comment at the start of cc-engine.el for more info."
   (c-put-char-property pos 'c-type value))
 
 (defun c-clear-c-type-property (from to value)
-  ;; Remove all occurences of the c-type property that has the given
+  ;; Remove all occurrences of the c-type property that has the given
   ;; value in the region between FROM and TO.  VALUE is assumed to not
   ;; be nil.
   ;;
@@ -555,7 +553,7 @@ the previous one if already at the beginning of one.  Only
 statements/declarations on the same level are considered, i.e. don't
 move into or out of sexps (not even normal expression parentheses).
 
-If point is already at the earliest statment within braces or parens,
+If point is already at the earliest statement within braces or parens,
 this function doesn't move back into any whitespace preceding it; it
 returns 'same in this case.
 
@@ -605,7 +603,7 @@ comment at the start of cc-engine.el for more info."
   ;; The bulk of this function is a pushdown automaton that looks at statement
   ;; boundaries and the tokens (such as "while") in c-opt-block-stmt-key.  Its
   ;; purpose is to keep track of nested statements, ensuring that such
-  ;; statments are skipped over in their entirety (somewhat akin to what C-M-p
+  ;; statements are skipped over in their entirety (somewhat akin to what C-M-p
   ;; does with nested braces/brackets/parentheses).
   ;;
   ;; Note: The position of a boundary is the following token.
@@ -2245,50 +2243,50 @@ comment at the start of cc-engine.el for more info."
            (setq cnt (1- cnt)))))
     (point)))
 
-(defun c-state-balance-parens-backwards (here top)
-  ;; Return the position of the opening paren/brace/bracket before HERE which
-  ;; matches the outermost close p/b/b between HERE and TOP, like this:
+(defun c-state-balance-parens-backwards (here- here+ top)
+  ;; Return the position of the opening paren/brace/bracket before HERE- which
+  ;; matches the outermost close p/b/b between HERE+ and TOP.  Except when
+  ;; there's a macro, HERE- and HERE+ are the same.  Like this:
   ;;
-  ;;      ......................................
-  ;;      |                                    |
-  ;;      (    [ ( ...........  )      ( )  ]  )
-  ;;      ^                 ^                       ^
-  ;;      |                 |                       |
-  ;;   return             HERE                     TOP
+  ;;     ............................................
+  ;;     |                                          |
+  ;;     (    [ ( .........#macro.. )      ( )  ]  )
+  ;;     ^                 ^     ^                         ^
+  ;;     |                 |     |                         |
+  ;;   return            HERE- HERE+                      TOP
   ;;
   ;; If there aren't enough opening paren/brace/brackets, return the position
-  ;; of the outermost one found, or HERE it there are none.  If there are no
-  ;; closeing p/b/bs between HERE and TOP, return HERE.  HERE and TOP must not
-  ;; be inside literals.  Only the accessible portion of the buffer will be
-  ;; scanned.
-
-  ;; PART 1: scan from `here' up to `top', accumulating ")"s which enclose
-  ;; `here'.  Go round the next loop each time we pass over such a ")".  These
-  ;; probably match "("s before `here'.
+  ;; of the outermost one found, or HERE- if there are none.  If there are no
+  ;; closeing p/b/bs between HERE+ and TOP, return HERE-.  HERE-/+ and TOP
+  ;; must not be inside literals.  Only the accessible portion of the buffer
+  ;; will be scanned.
+
+  ;; PART 1: scan from `here+' up to `top', accumulating ")"s which enclose
+  ;; `here'.  Go round the next loop each time we pass over such a ")".         These
+  ;; probably match "("s before `here-'.
   (let (pos pa ren+1 lonely-rens)
     (save-excursion
       (save-restriction
        (narrow-to-region (point-min) top) ; This can move point, sometimes.
-       (setq pos here)
+       (setq pos here+)
        (c-safe
          (while
              (setq ren+1 (scan-lists pos 1 1)) ; might signal
            (setq lonely-rens (cons ren+1 lonely-rens)
                  pos ren+1)))))
 
-      ;; PART 2: Scan back before `here' searching for the "("s
+      ;; PART 2: Scan back before `here-' searching for the "("s
       ;; matching/mismatching the ")"s found above. We only need to direct the
       ;; caller to scan when we've encountered unmatched right parens.
-      (when lonely-rens
-       (setq pos here)
-       (c-safe
-         (while
-             (and lonely-rens          ; actual values aren't used.
-                  (setq pa (scan-lists pos -1 1)))
-           (setq pos pa)
-           (setq lonely-rens (cdr lonely-rens)))) ;)
-       )
-      pos))
+    (setq pos here-)
+    (when lonely-rens
+      (c-safe
+       (while
+           (and lonely-rens            ; actual values aren't used.
+                (setq pa (scan-lists pos -1 1)))
+         (setq pos pa)
+         (setq lonely-rens (cdr lonely-rens)))))
+    pos))
 
 (defun c-parse-state-get-strategy (here good-pos)
   ;; Determine the scanning strategy for adjusting `c-parse-state', attempting
@@ -2591,7 +2589,7 @@ comment at the start of cc-engine.el for more info."
   (save-restriction
     (narrow-to-region 1 (point-max))
     (save-excursion
-      (let* ((in-macro-start   ; point-max or beginning of macro containing it
+      (let* ((in-macro-start   ; start of macro containing (point-max) or nil.
              (save-excursion
                (goto-char (point-max))
                (and (c-beginning-of-macro)
@@ -2624,7 +2622,7 @@ comment at the start of cc-engine.el for more info."
                           (< (point-max) c-state-old-cpp-end)))
                  (point-max)
                (min (point-max) c-state-old-cpp-beg)))
-       (while (and c-state-cache (> (c-state-cache-top-lparen) upper-lim))
+       (while (and c-state-cache (>= (c-state-cache-top-lparen) upper-lim))
          (setq c-state-cache (cdr c-state-cache)))
        ;; If `upper-lim' is inside the last recorded brace pair, remove its
        ;; RBrace and indicate we'll need to search backwards for a previous
@@ -2641,7 +2639,9 @@ comment at the start of cc-engine.el for more info."
        ;; (car c-state-cache).  There can be no open parens/braces/brackets
        ;; between `good-pos'/`good-pos-actual-macro-start' and (point-max),
        ;; due to the interface spec to this function.
-       (setq pos (if good-pos-actual-macro-end
+       (setq pos (if (and good-pos-actual-macro-end
+                          (not (eq good-pos-actual-macro-start
+                                   in-macro-start)))
                      (1+ good-pos-actual-macro-end) ; get outside the macro as
                                        ; marked by a `category' text property.
                    good-pos))
@@ -2744,6 +2744,7 @@ comment at the start of cc-engine.el for more info."
        lit         ; (START . END) of a literal containing some point.
        here-lit-start here-lit-end     ; bounds of literal containing `here'
                                        ; or `here' itself.
+       here- here+                  ; start/end of macro around HERE, or HERE
        (here-bol (c-point 'bol here))
        (too-far-back (max (- here c-state-cache-too-far) 1)))
 
@@ -2756,57 +2757,73 @@ comment at the start of cc-engine.el for more info."
     ;; At this stage, (> pos here);
     ;; (< (c-state-cache-top-lparen) here)  (or is nil).
 
-    ;; CASE 1: The top of the cache is a brace pair which now encloses `here'.
-    ;; As good-pos, return the address. of the "{".
-    (if (and (consp (car c-state-cache))
-            (> (cdar c-state-cache) here))
-       ;; Since we've no knowledge of what's inside these braces, we have no
-       ;; alternative but to direct the caller to scan the buffer from the
-       ;; opening brace.
-       (progn
-         (setq pos (caar c-state-cache))
-         (setcar c-state-cache pos)
-         (list (1+ pos) pos t)) ; return value.  We've just converted a brace
-                                ; pair entry into a { entry, so the caller
-                                ; needs to search for a brace pair before the
-                                ; {.
-
-      ;; ;; `here' might be inside a literal.  Check for this.
-      (setq lit (c-state-literal-at here)
-           here-lit-start (or (car lit) here)
-           here-lit-end (or (cdr lit) here))
-
-      ;; `here' might be nested inside any depth of parens (or brackets but
-      ;; not braces).  Scan backwards to find the outermost such opening
-      ;; paren, if there is one.  This will be the scan position to return.
-      (save-restriction
-       (narrow-to-region cache-pos (point-max))
-       (setq pos (c-state-balance-parens-backwards here-lit-end pos)))
-
-      (if (< pos here-lit-start)
-         ;; CASE 2: Address of outermost ( or [ which now encloses `here',
-         ;; but didn't enclose the (previous) `c-state-cache-good-pos'.  If
-         ;; there is a brace pair preceding this, it will already be in
-         ;; `c-state-cache', unless there was a brace pair after it,
-         ;; i.e. there'll only be one to scan for if we've just deleted one.
-         (list pos (and dropped-cons pos) t) ; Return value.
-
-       ;; `here' isn't enclosed in a (previously unrecorded) bracket/paren.
-       ;; Further forward scanning isn't needed, but we still need to find a
-       ;; GOOD-POS.  Step out of all enclosing "("s on HERE's line.
+    (cond
+     ((and (consp (car c-state-cache))
+          (> (cdar c-state-cache) here))
+      ;; CASE 1: The top of the cache is a brace pair which now encloses
+      ;; `here'.  As good-pos, return the address. of the "{".  Since we've no
+      ;; knowledge of what's inside these braces, we have no alternative but
+      ;; to direct the caller to scan the buffer from the opening brace.
+      (setq pos (caar c-state-cache))
+      (setcar c-state-cache pos)
+      (list (1+ pos) pos t)) ; return value.  We've just converted a brace pair
+                            ; entry into a { entry, so the caller needs to
+                            ; search for a brace pair before the {.
+
+     ;; `here' might be inside a literal.  Check for this.
+     ((progn
+       (setq lit (c-state-literal-at here)
+             here-lit-start (or (car lit) here)
+             here-lit-end (or (cdr lit) here))
+       ;; Has `here' just "newly entered" a macro?
+       (save-excursion
+         (goto-char here-lit-start)
+         (if (and (c-beginning-of-macro)
+                  (or (null c-state-old-cpp-beg)
+                      (not (= (point) c-state-old-cpp-beg))))
+             (progn
+               (setq here- (point))
+               (c-end-of-macro)
+               (setq here+ (point)))
+           (setq here- here-lit-start
+                 here+ here-lit-end)))
+
+       ;; `here' might be nested inside any depth of parens (or brackets but
+       ;; not braces).  Scan backwards to find the outermost such opening
+       ;; paren, if there is one.  This will be the scan position to return.
+       (save-restriction
+         (narrow-to-region cache-pos (point-max))
+         (setq pos (c-state-balance-parens-backwards here- here+ pos)))
+       nil))                           ; for the cond
+
+     ((< pos here-lit-start)
+      ;; CASE 2: Address of outermost ( or [ which now encloses `here', but
+      ;; didn't enclose the (previous) `c-state-cache-good-pos'.  If there is
+      ;; a brace pair preceding this, it will already be in `c-state-cache',
+      ;; unless there was a brace pair after it, i.e. there'll only be one to
+      ;; scan for if we've just deleted one.
+      (list pos (and dropped-cons pos) t)) ; Return value.
+
+      ;; `here' isn't enclosed in a (previously unrecorded) bracket/paren.
+      ;; Further forward scanning isn't needed, but we still need to find a
+      ;; GOOD-POS.  Step out of all enclosing "("s on HERE's line.
+     ((progn
        (save-restriction
          (narrow-to-region here-bol (point-max))
          (setq pos here-lit-start)
          (c-safe (while (setq pa (scan-lists pos -1 1))
                    (setq pos pa))))    ; might signal
-       (if (setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
-           ;; CASE 3: After a }/)/] before `here''s BOL.
-           (list (1+ ren) (and dropped-cons pos) nil) ; Return value
+       nil))                           ; for the cond
 
-         ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
-         ;; literal containing it.
-         (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
-         (list good-pos (and dropped-cons good-pos) nil))))))
+     ((setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
+       ;; CASE 3: After a }/)/] before `here''s BOL.
+      (list (1+ ren) (and dropped-cons pos) nil)) ; Return value
+
+     (t
+      ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
+      ;; literal containing it.
+      (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
+      (list good-pos (and dropped-cons good-pos) nil)))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2996,9 +3013,11 @@ comment at the start of cc-engine.el for more info."
   ;; 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 c-state-old-cpp-beg
+   (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 c-state-old-cpp-end
+       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)))))
@@ -3029,8 +3048,9 @@ comment at the start of cc-engine.el for more info."
              (c-parse-state-1))
           (c-with-cpps-commented-out
            (c-parse-state-1))))
-      (setq c-state-old-cpp-beg here-cpp-beg
-           c-state-old-cpp-end here-cpp-end))))
+      (setq c-state-old-cpp-beg (and here-cpp-beg (copy-marker here-cpp-beg t))
+           c-state-old-cpp-end (and here-cpp-end (copy-marker here-cpp-end t)))
+      )))
 
 ;; Debug tool to catch cache inconsistencies.  This is called from
 ;; 000tests.el.
@@ -4394,7 +4414,7 @@ comment at the start of cc-engine.el for more info."
   ;;    `c-decl-prefix-or-start-re' when that submatch matches.
   ;; o  The start of each `c-decl-prefix-or-start-re' match when
   ;;    submatch 1 doesn't match.
-  ;; o  The first token after the end of each occurence of the
+  ;; o  The first token after the end of each occurrence of the
   ;;    `c-type' text property with the value `c-decl-end', provided
   ;;    `c-type-decl-end-used' is set.
   ;;
@@ -4877,7 +4897,190 @@ comment at the start of cc-engine.el for more info."
        )))
 
 \f
-;; Handling of small scale constructs like types and names.
+;; Setting and removing syntax properties on < and > in languages (C++
+;; and Java) where they can be template/generic delimiters as well as
+;; their normal meaning of "less/greater than".
+
+;; Normally, < and > have syntax 'punctuation'.  When they are found to
+;; be delimiters, they are marked as such with the category properties
+;; c-<-as-paren-syntax, c->-as-paren-syntax respectively.
+
+;; STRATEGY:
+;;
+;; It is impossible to determine with certainty whether a <..> pair in
+;; C++ is two comparison operators or is template delimiters, unless
+;; one duplicates a lot of a C++ compiler.  For example, the following
+;; code fragment:
+;;
+;;     foo (a < b, c > d) ;
+;;
+;; could be a function call with two integer parameters (each a
+;; relational expression), or it could be a constructor for class foo
+;; taking one parameter d of templated type "a < b, c >".  They are
+;; somewhat easier to distinguish in Java.
+;;
+;; The strategy now (2010-01) adopted is to mark and unmark < and
+;; > IN MATCHING PAIRS ONLY.  [Previously, they were marked
+;; individually when their context so indicated.  This gave rise to
+;; intractible problems when one of a matching pair was deleted, or
+;; pulled into a literal.]
+;;
+;; At each buffer change, the syntax-table properties are removed in a
+;; before-change function and reapplied, when needed, in an
+;; after-change function.  It is far more important that the
+;; properties get removed when they they are spurious than that they
+;; be present when wanted.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun c-clear-<-pair-props (&optional pos)
+  ;; POS (default point) is at a < character.  If it is marked with
+  ;; open paren syntax-table text property, remove the property,
+  ;; together with the close paren property on the matching > (if
+  ;; any).
+  (save-excursion
+    (if pos
+       (goto-char pos)
+      (setq pos (point)))
+    (when (equal (c-get-char-property (point) 'syntax-table)
+                c-<-as-paren-syntax)
+      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
+       (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))))
+
+(defun c-clear->-pair-props (&optional pos)
+  ;; POS (default point) is at a > character.  If it is marked with
+  ;; close paren syntax-table property, remove the property, together
+  ;; with the open paren property on the matching < (if any).
+  (save-excursion
+    (if pos
+       (goto-char pos)
+      (setq pos (point)))
+    (when (equal (c-get-char-property (point) 'syntax-table)
+                c->-as-paren-syntax)
+      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
+       (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))))
+
+(defun c-clear-<>-pair-props (&optional pos)
+  ;; POS (default point) is at a < or > character.  If it has an
+  ;; open/close paren syntax-table property, remove this property both
+  ;; from the current character and its partner (which will also be
+  ;; thusly marked).
+  (cond
+   ((eq (char-after) ?\<)
+    (c-clear-<-pair-props pos))
+   ((eq (char-after) ?\>)
+    (c-clear->-pair-props pos))
+   (t (c-benign-error
+       "c-clear-<>-pair-props called from wrong position"))))
+
+(defun c-clear-<-pair-props-if-match-after (lim &optional pos)
+  ;; POS (default point) is at a < character.  If it is both marked
+  ;; with open/close paren syntax-table property, and has a matching >
+  ;; (also marked) which is after LIM, remove the property both from
+  ;; the current > and its partner.  Return t when this happens, nil
+  ;; when it doesn't.
+  (save-excursion
+    (if pos
+       (goto-char pos)
+      (setq pos (point)))
+    (when (equal (c-get-char-property (point) 'syntax-table)
+                c-<-as-paren-syntax)
+      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
+       (c-go-list-forward))
+      (when (and (>= (point) lim)
+                (equal (c-get-char-property (1- (point)) 'syntax-table)
+                       c->-as-paren-syntax)) ; should always be true.
+       (c-unmark-<->-as-paren (1- (point)))
+       (c-unmark-<->-as-paren pos))
+      t)))
+
+(defun c-clear->-pair-props-if-match-before (lim &optional pos)
+  ;; POS (default point) is at a > character.  If it is both marked
+  ;; with open/close paren syntax-table property, and has a matching <
+  ;; (also marked) which is before LIM, remove the property both from
+  ;; the current < and its partner.  Return t when this happens, nil
+  ;; when it doesn't.
+  (save-excursion
+    (if pos
+       (goto-char pos)
+      (setq pos (point)))
+    (when (equal (c-get-char-property (point) 'syntax-table)
+                c->-as-paren-syntax)
+      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
+       (c-go-up-list-backward))
+      (when (and (<= (point) lim)
+                (equal (c-get-char-property (point) 'syntax-table)
+                       c-<-as-paren-syntax)) ; should always be true.
+       (c-unmark-<->-as-paren (point))
+       (c-unmark-<->-as-paren pos))
+      t)))
+
+;; Set by c-common-init in cc-mode.el.
+(defvar c-new-BEG)
+(defvar c-new-END)
+
+(defun c-before-change-check-<>-operators (beg end)
+  ;; Unmark certain pairs of "< .... >" which are currently marked as
+  ;; template/generic delimiters.  (This marking is via syntax-table
+  ;; text properties).
+  ;;
+  ;; These pairs are those which are in the current "statement" (i.e.,
+  ;; the region between the {, }, or ; before BEG and the one after
+  ;; END), and which enclose any part of the interval (BEG END).
+  ;;
+  ;; Note that in C++ (?and Java), template/generic parens cannot
+  ;; enclose a brace or semicolon, so we use these as bounds on the
+  ;; region we must work on.
+  ;;
+  ;; This function is called from before-change-functions (via
+  ;; c-get-state-before-change-functions).  Thus the buffer is widened,
+  ;; and point is undefined, both at entry and exit.
+  ;;
+  ;; FIXME!!!  This routine ignores the possibility of macros entirely.
+  ;; 2010-01-29.
+  (save-excursion
+    (let ((beg-lit-limits (progn (goto-char beg) (c-literal-limits)))
+         (end-lit-limits (progn (goto-char end) (c-literal-limits)))
+         new-beg new-end need-new-beg need-new-end)
+      ;; Locate the barrier before the changed region
+      (goto-char  (if beg-lit-limits (car beg-lit-limits) beg))
+      (c-syntactic-skip-backward "^;{}" (max (- beg 2048) (point-min)))
+      (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)
+       (if (c-clear-<-pair-props-if-match-after beg (1- (point)))
+           (setq need-new-beg t)))
+
+      ;; Locate the barrier after END.
+      (goto-char (if end-lit-limits (cdr end-lit-limits) end))
+      (c-syntactic-re-search-forward "[;{}]"
+                                    (min (+ end 2048) (point-max)) 'end)
+      (setq new-end (point))
+
+      ;; 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)
+       (if (c-clear->-pair-props-if-match-before end)
+           (setq need-new-end t)))
+
+      ;; Extend the fontification region, if needed.
+      (when need-new-beg
+       (goto-char new-beg)
+       (c-forward-syntactic-ws)
+       (and (< (point) c-new-BEG) (setq c-new-BEG (point))))
+
+      (when need-new-end
+       (and (> new-end c-new-END) (setq c-new-END new-end))))))
+
+
 
 (defun c-after-change-check-<>-operators (beg end)
   ;; This is called from `after-change-functions' when
@@ -4899,7 +5102,7 @@ comment at the start of cc-engine.el for more info."
                 (< beg (setq beg (match-end 0))))
        (while (progn (skip-chars-forward "^<>" beg)
                      (< (point) beg))
-         (c-clear-char-property (point) 'syntax-table)
+         (c-clear-<>-pair-props)
          (forward-char))))
 
     (when (< beg end)
@@ -4914,9 +5117,13 @@ comment at the start of cc-engine.el for more info."
                   (< end (setq end (match-end 0))))
          (while (progn (skip-chars-forward "^<>" end)
                        (< (point) end))
-           (c-clear-char-property (point) 'syntax-table)
+           (c-clear-<>-pair-props)
            (forward-char)))))))
 
+
+\f
+;; Handling of small scale constructs like types and names.
+
 ;; Dynamically bound variable that instructs `c-forward-type' to also
 ;; treat possible types (i.e. those that it normally returns 'maybe or
 ;; 'found for) as actual types (and always return 'found for them).
@@ -5161,6 +5368,11 @@ comment at the start of cc-engine.el for more info."
       (goto-char safe-pos)
       t)))
 
+;; cc-mode requires cc-fonts.
+(declare-function c-fontify-recorded-types-and-refs "cc-fonts" ())
+
+(defvar c-forward-<>-arglist-recur-depth)
+
 (defun c-forward-<>-arglist (all-types)
   ;; The point is assumed to be at a "<".  Try to treat it as the open
   ;; paren of an angle bracket arglist and move forward to the
@@ -5186,7 +5398,8 @@ comment at the start of cc-engine.el for more info."
        ;; If `c-record-type-identifiers' is set then activate
        ;; recording of any found types that constitute an argument in
        ;; the arglist.
-       (c-record-found-types (if c-record-type-identifiers t)))
+       (c-record-found-types (if c-record-type-identifiers t))
+       (c-forward-<>-arglist-recur--depth 0))
     (if (catch 'angle-bracket-arglist-escape
          (setq c-record-found-types
                (c-forward-<>-arglist-recur all-types)))
@@ -5196,12 +5409,21 @@ comment at the start of cc-engine.el for more info."
                  ;; `nconc' doesn't mind that the tail of
                  ;; `c-record-found-types' is t.
                  (nconc c-record-found-types c-record-type-identifiers)))
+           (if (c-major-mode-is 'java-mode) (c-fontify-recorded-types-and-refs))
          t)
 
       (goto-char start)
       nil)))
 
 (defun c-forward-<>-arglist-recur (all-types)
+
+  ;; Temporary workaround for Bug#7722.
+  (when (boundp 'c-forward-<>-arglist-recur--depth)
+    (if (> c-forward-<>-arglist-recur--depth 200)
+       (error "Max recursion depth reached in <> arglist")
+      (setq c-forward-<>-arglist-recur--depth
+           (1+ c-forward-<>-arglist-recur--depth))))
+
   ;; Recursive part of `c-forward-<>-arglist'.
   ;;
   ;; This function might do hidden buffer changes.
@@ -5215,7 +5437,6 @@ comment at the start of cc-engine.el for more info."
        ;; List that collects the positions after the argument
        ;; separating ',' in the arglist.
        arg-start-pos)
-
     ;; If the '<' has paren open syntax then we've marked it as an angle
     ;; bracket arglist before, so skip to the end.
     (if (and (not c-parse-and-markup-<>-arglists)
@@ -5226,7 +5447,6 @@ comment at the start of cc-engine.el for more info."
          (if (and (c-go-up-list-forward)
                   (eq (char-before) ?>))
              t
-
            ;; Got unmatched paren angle brackets.  We don't clear the paren
            ;; syntax properties and retry, on the basis that it's very
            ;; unlikely that paren angle brackets become operators by code
@@ -5236,67 +5456,46 @@ comment at the start of cc-engine.el for more info."
            nil))
 
       (forward-char)
+
       (unless (looking-at c-<-op-cont-regexp)
        (while (and
                (progn
-
-                 (when c-record-type-identifiers
-                   (if all-types
-
-                       ;; All encountered identifiers are types, so set the
-                       ;; promote flag and parse the type.
-                       (progn
-                         (c-forward-syntactic-ws)
+                 (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))
+                           (let ((c-promote-possible-types t)
+                                 (c-record-found-types t))
                              (c-forward-type))))
 
-                     ;; Check if this arglist argument is a sole type.  If
-                     ;; it's known then it's recorded in
-                     ;; `c-record-type-identifiers'.  If it only is found
-                     ;; then it's recorded in `c-record-found-types' which we
-                     ;; might roll back if it turns out that this isn't an
-                     ;; angle bracket arglist afterall.
-                     (when (memq (char-before) '(?, ?<))
-                       (let ((orig-record-found-types c-record-found-types))
+                       (c-forward-syntactic-ws)
+
+                       (when (or (looking-at "extends")
+                                 (looking-at "super"))
+                         (forward-word)
                          (c-forward-syntactic-ws)
-                         (and (memq (c-forward-type) '(known found))
-                              (not (looking-at "[,>]"))
-                              ;; A found type was recorded but it's not the
-                              ;; only thing in the arglist argument, so reset
-                              ;; `c-record-found-types'.
-                              (setq c-record-found-types
-                                    orig-record-found-types))))))
+                         (let ((c-promote-possible-types t)
+                               (c-record-found-types t))
+                           (c-forward-type)
+                           (c-forward-syntactic-ws))))))
 
                  (setq pos (point))
-                 (or (when (eq (char-after) ?>)
-                       ;; Must check for '>' at the very start separately,
-                       ;; since the regexp below has to avoid ">>" without
-                       ;; using \\=.
-                       (forward-char)
-                       t)
-
-                     ;; Note: These regexps exploit the match order in \| so
-                     ;; that "<>" is matched by "<" rather than "[^>:-]>".
-                     (c-syntactic-re-search-forward
-                      (if c-restricted-<>-arglists
-                          ;; Stop on ',', '|', '&', '+' and '-' to catch
-                          ;; common binary operators that could be between
-                          ;; two comparison expressions "a<b" and "c>d".
-                          "[<;{},|&+-]\\|\\([^>:-]>\\)"
-                        ;; Otherwise we still stop on ',' to find the
-                        ;; argument start positions.
-                        "[<;{},]\\|\\([^>:-]>\\)")
-                      nil 'move t t 1)
-
-                     ;; If the arglist starter has lost its open paren
-                     ;; syntax but not the closer, we won't find the
-                     ;; closer above since we only search in the
-                     ;; balanced sexp.  In that case we stop just short
-                     ;; of it so check if the following char is the closer.
-                     (when (eq (char-after) ?>)
-                       (forward-char)
-                       t)))
+
+                 ;; Note: These regexps exploit the match order in \| so
+                 ;; that "<>" is matched by "<" rather than "[^>:-]>".
+                 (c-syntactic-re-search-forward
+                  ;; Stop on ',', '|', '&', '+' and '-' to catch
+                  ;; common binary operators that could be between
+                  ;; two comparison expressions "a<b" and "c>d".
+                  "[<;{},|+&-]\\|[>)]"
+                  nil t t))
 
                (cond
                 ((eq (char-before) ?>)
@@ -5321,7 +5520,6 @@ comment at the start of cc-engine.el for more info."
 
                 ((eq (char-before) ?<)
                  ;; Either an operator starting with '<' or a nested arglist.
-
                  (setq pos (point))
                  (let (id-start id-end subres keyword-match)
                    (if (if (looking-at c-<-op-cont-regexp)
@@ -5344,8 +5542,8 @@ comment at the start of cc-engine.el for more info."
                                (setq id-start (point))))
 
                            (setq subres
-                                 (let ((c-record-type-identifiers nil)
-                                       (c-record-found-types nil))
+                                 (let ((c-promote-possible-types t)
+                                       (c-record-found-types t))
                                    (c-forward-<>-arglist-recur
                                     (and keyword-match
                                          (c-keyword-member
@@ -5372,9 +5570,11 @@ comment at the start of cc-engine.el for more info."
                          (c-record-type-id (cons id-start id-end))))))
                  t)
 
-                ((and (eq (char-before) ?,)
-                      (not c-restricted-<>-arglists))
-                 ;; Just another argument.  Record the position.  The
+                ((and (not c-restricted-<>-arglists)
+                      (or (and (eq (char-before) ?&)
+                               (not (eq (char-after) ?&)))
+                          (eq (char-before) ?,)))
+                 ;; 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)))
@@ -5385,7 +5585,6 @@ comment at the start of cc-engine.el for more info."
                  ;; it's useless to try to find a surrounding arglist
                  ;; if we're nested.
                  (throw 'angle-bracket-arglist-escape nil))))))
-
       (if res
          (or c-record-found-types t)))))
 
@@ -5456,17 +5655,23 @@ comment at the start of cc-engine.el for more info."
 
 (defun c-forward-name ()
   ;; Move forward over a complete name if at the beginning of one,
-  ;; stopping at the next following token.  If the point is not at
-  ;; something that are recognized as name then it stays put.  A name
-  ;; could be something as simple as "foo" in C or something as
+  ;; stopping at the next following token.  A keyword, as such,
+  ;; doesn't count as a name.  If the point is not at something that
+  ;; is recognized as a name then it stays put.
+  ;;
+  ;; A name could be something as simple as "foo" in C or something as
   ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> ::
   ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short
   ;; int>::*volatile const" in C++ (this function is actually little
   ;; more than a `looking-at' call in all modes except those that,
-  ;; like C++, have `c-recognize-<>-arglists' set).  Return nil if no
-  ;; name is found, 'template if it's an identifier ending with an
-  ;; angle bracket arglist, 'operator of it's an operator identifier,
-  ;; or t if it's some other kind of name.
+  ;; like C++, have `c-recognize-<>-arglists' set).
+  ;;
+  ;; Return
+  ;; o - nil if no name is found;
+  ;; o - 'template if it's an identifier ending with an angle bracket
+  ;;   arglist;
+  ;; o - 'operator of it's an operator identifier;
+  ;; o - t if it's some other kind of name.
   ;;
   ;; This function records identifier ranges on
   ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
@@ -5588,9 +5793,8 @@ comment at the start of cc-engine.el for more info."
              ((and c-recognize-<>-arglists
                    (eq (char-after) ?<))
               ;; Maybe an angle bracket arglist.
-
-              (when (let (c-record-type-identifiers
-                          c-record-found-types)
+              (when (let ((c-record-type-identifiers t)
+                          (c-record-found-types t))
                       (c-forward-<>-arglist nil))
 
                 (c-add-type start (1+ pos))
@@ -5619,16 +5823,28 @@ comment at the start of cc-engine.el for more info."
     (goto-char pos)
     res))
 
-(defun c-forward-type ()
+(defun c-forward-type (&optional brace-block-too)
   ;; Move forward over a type spec if at the beginning of one,
-  ;; stopping at the next following token.  Return t if it's a known
-  ;; type that can't be a name or other expression, 'known if it's an
-  ;; otherwise known type (according to `*-font-lock-extra-types'),
-  ;; 'prefix if it's a known prefix of a type, 'found if it's a type
-  ;; that matches one in `c-found-types', 'maybe if it's an identfier
-  ;; that might be a type, or nil if it can't be a type (the point
-  ;; isn't moved then).  The point is assumed to be at the beginning
-  ;; of a token.
+  ;; stopping at the next following token.  The keyword "typedef"
+  ;; isn't part of a type spec here.
+  ;;
+  ;; BRACE-BLOCK-TOO, when non-nil, means move over the brace block in
+  ;; constructs like "struct foo {...} bar ;" or "struct {...} bar;".
+  ;; The current (2009-03-10) intention is to convert all uses of
+  ;; `c-forward-type' to call with this parameter set, then to
+  ;; eliminate it.
+  ;;
+  ;; Return
+  ;;   o - t if it's a known type that can't be a name or other
+  ;;     expression;
+  ;;   o - 'known if it's an otherwise known type (according to
+  ;;     `*-font-lock-extra-types');
+  ;;   o - 'prefix if it's a known prefix of a type;
+  ;;   o - 'found if it's a type that matches one in `c-found-types';
+  ;;   o - 'maybe if it's an identfier that might be a type; or
+  ;;   o -  nil if it can't be a type (the point isn't moved then).
+  ;;
+  ;; The point is assumed to be at the beginning of a token.
   ;;
   ;; Note that this function doesn't skip past the brace definition
   ;; that might be considered part of the type, e.g.
@@ -5639,37 +5855,48 @@ comment at the start of cc-engine.el for more info."
   ;; `c-record-type-identifiers' is non-nil.
   ;;
   ;; This function might do hidden buffer changes.
+  (when (and c-recognize-<>-arglists
+            (looking-at "<"))
+    (c-forward-<>-arglist t)
+    (c-forward-syntactic-ws))
 
   (let ((start (point)) pos res name-res id-start id-end id-range)
 
     ;; Skip leading type modifiers.  If any are found we know it's a
     ;; prefix of a type.
-    (when c-opt-type-modifier-key
+    (when c-opt-type-modifier-key ; e.g. "const" "volatile", but NOT "typedef"
       (while (looking-at c-opt-type-modifier-key)
        (goto-char (match-end 1))
        (c-forward-syntactic-ws)
        (setq res 'prefix)))
 
     (cond
-     ((looking-at c-type-prefix-key)
-      ;; Looking at a keyword that prefixes a type identifier,
-      ;; e.g. "class".
+     ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
+                                    ; "typedef".
       (goto-char (match-end 1))
       (c-forward-syntactic-ws)
       (setq pos (point))
-      (if (memq (setq name-res (c-forward-name)) '(t template))
-         (progn
-           (when (eq name-res t)
-             ;; In many languages the name can be used without the
-             ;; prefix, so we add it to `c-found-types'.
-             (c-add-type pos (point))
-             (when (and c-record-type-identifiers
-                        c-last-identifier-range)
-               (c-record-type-id c-last-identifier-range)))
-           (setq res t))
-       ;; Invalid syntax.
-       (goto-char start)
-       (setq res nil)))
+
+      (setq name-res (c-forward-name))
+      (setq res (not (null name-res)))
+      (when (eq name-res t)
+       ;; In many languages the name can be used without the
+       ;; prefix, so we add it to `c-found-types'.
+       (c-add-type pos (point))
+       (when (and c-record-type-identifiers
+                  c-last-identifier-range)
+         (c-record-type-id c-last-identifier-range)))
+      (when (and brace-block-too
+                (memq res '(t nil))
+                (eq (char-after) ?\{)
+                (save-excursion
+                  (c-safe
+                    (progn (c-forward-sexp)
+                           (c-forward-syntactic-ws)
+                           (setq pos (point))))))
+       (goto-char pos)
+       (setq res t))
+      (unless res (goto-char start)))  ; invalid syntax
 
      ((progn
        (setq pos nil)
@@ -5759,14 +5986,13 @@ 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)
+       (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
@@ -5776,7 +6002,7 @@ comment at the start of cc-engine.el for more info."
          (goto-char (match-end 1))
          (c-forward-syntactic-ws)))
 
-      (when c-opt-type-concat-key
+      (when c-opt-type-concat-key      ; Only/mainly for pike.
        ;; Look for a trailing operator that concatenates the type
        ;; with a following one, and if so step past that one through
        ;; a recursive call.  Note that we don't record concatenated
@@ -5838,6 +6064,18 @@ comment at the start of cc-engine.el for more info."
 
     res))
 
+(defun c-forward-annotation ()
+  ;; Used for Java code only at the moment.  Assumes point is on the
+  ;; @, moves forward an annotation.  returns nil if there is no
+  ;; annotation at point.
+  (and (looking-at "@")
+       (progn (forward-char) t)
+       (c-forward-type)
+       (progn (c-forward-syntactic-ws) t)
+       (if (looking-at "(")
+          (c-go-list-forward)
+         t)))
+
 \f
 ;; Handling of large scale constructs like statements and declarations.
 
@@ -5915,11 +6153,15 @@ comment at the start of cc-engine.el for more info."
   ;;      car ^                                     ^ point
   ;;     Foo::Foo (int b) : Base (b) {}
   ;; car ^                ^ point
-  ;;
-  ;;   The cdr of the return value is non-nil iff a `c-typedef-decl-kwds'
-  ;;   specifier (e.g. class, struct, enum, typedef) is found in the
-  ;;   declaration, i.e. the declared identifier(s) are types.
-  ;;
+  ;; 
+  ;;   The cdr of the return value is non-nil when a
+  ;;   `c-typedef-decl-kwds' specifier is found in the declaration.
+  ;;   Specifically it is a dotted pair (A . B) where B is t when a
+  ;;   `c-typedef-kwds' ("typedef") is present, and A is t when some
+  ;;   other `c-typedef-decl-kwds' (e.g. class, struct, enum)
+  ;;   specifier is present.  I.e., (some of) the declared
+  ;;   identifier(s) are types.
+  ;; 
   ;; If a cast is parsed:
   ;;
   ;;   The point is left at the first token after the closing paren of
@@ -5977,9 +6219,11 @@ comment at the start of cc-engine.el for more info."
        ;; If `backup-at-type' is nil then the other variables have
        ;; undefined values.
        backup-at-type backup-type-start backup-id-start
-       ;; Set if we've found a specifier that makes the defined
-       ;; identifier(s) types.
+       ;; Set if we've found a specifier (apart from "typedef") that makes
+       ;; the defined identifier(s) types.
        at-type-decl
+       ;; Set if we've a "typedef" keyword.
+       at-typedef
        ;; Set if we've found a specifier that can start a declaration
        ;; where there's no type.
        maybe-typeless
@@ -6007,6 +6251,9 @@ comment at the start of cc-engine.el for more info."
        (save-rec-type-ids c-record-type-identifiers)
        (save-rec-ref-ids c-record-ref-identifiers))
 
+    (while (c-forward-annotation)
+      (c-forward-syntactic-ws))
+
     ;; Check for a type.  Unknown symbols are treated as possible
     ;; types, but they could also be specifiers disguised through
     ;; macros like __INLINE__, so we recognize both types and known
@@ -6016,12 +6263,14 @@ comment at the start of cc-engine.el for more info."
 
          ;; Look for a specifier keyword clause.
          (when (looking-at c-prefix-spec-kwds-re)
+           (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))))
 
-         (when (setq found-type (c-forward-type))
+         (when (setq found-type (c-forward-type t)) ; brace-block-too
            ;; Found a known or possible type or a prefix of a known type.
 
            (when at-type
@@ -6086,6 +6335,8 @@ comment at the start of cc-engine.el for more info."
                          (setq backup-maybe-typeless t)))
 
                    (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
+                     ;; This test only happens after we've scanned a type.
+                     ;; So, with valid syntax, kwd-sym can't be 'typedef.
                      (setq at-type-decl t))
                    (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
                      (setq maybe-typeless t))
@@ -6340,13 +6591,14 @@ comment at the start of cc-engine.el for more info."
                ;; CASE 3
                (when (= (point) start)
                  ;; Got a plain list of identifiers.  If a colon follows it's
-                 ;; a valid label.  Otherwise the last one probably is the
-                 ;; declared identifier and we should back up to the previous
-                 ;; type, providing it isn't a cast.
-                 (if (eq (char-after) ?:)
-                     ;; If we've found a specifier keyword then it's a
-                     ;; declaration regardless.
-                     (throw 'at-decl-or-cast (eq at-decl-or-cast t))
+                  ;; a valid label.  Otherwise the last one probably is the
+                  ;; declared identifier and we should back up to the previous
+                  ;; type, providing it isn't a cast.
+                  (if (and (eq (char-after) ?:)
+                           (not (c-major-mode-is 'java-mode)))
+                      ;; If we've found a specifier keyword then it's a
+                      ;; declaration regardless.
+                      (throw 'at-decl-or-cast (eq at-decl-or-cast t))
                    (setq backup-if-not-cast t)
                    (throw 'at-decl-or-cast t)))
 
@@ -6684,7 +6936,9 @@ comment at the start of cc-engine.el for more info."
            (goto-char type-start)
            (c-forward-type))))
 
-      (cons id-start at-type-decl))
+      (cons id-start
+           (and (or at-type-decl at-typedef)
+                (cons at-type-decl at-typedef))))
 
      (t
       ;; False alarm.  Restore the recorded ranges.
@@ -8307,7 +8561,7 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;; This function might do hidden buffer changes.
 
-  (let (special-brace-list)
+  (let (special-brace-list placeholder)
     (goto-char indent-point)
     (skip-chars-forward " \t")
 
@@ -8414,6 +8668,22 @@ comment at the start of cc-engine.el for more info."
       (c-add-stmt-syntax 'func-decl-cont nil t
                         containing-sexp paren-state))
 
+     ;;CASE F: continued statement and the only preceding items are
+     ;;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 containing-sexp)
+       (c-add-syntax 'annotation-var-cont (point)))
+
      ;; CASE D: continued statement.
      (t
       (c-beginning-of-statement-1 containing-sexp)
@@ -8513,7 +8783,6 @@ comment at the start of cc-engine.el for more info."
        (when (and containing-sexp
                   (eq (char-after containing-sexp) ?\())
          (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
-
        ;; cache char before and after indent point, and move point to
        ;; the most likely position to perform the majority of tests
        (goto-char indent-point)
@@ -9263,23 +9532,36 @@ comment at the start of cc-engine.el for more info."
            (c-add-syntax 'objc-method-args-cont placeholder))
 
           ;; CASE 5L: we are at the first argument of a template
-          ;; arglist that begins on the previous line.
-          ((and c-recognize-<>-arglists
-                (eq (char-before) ?<)
-                (setq placeholder (1- (point)))
-                (not (and c-overloadable-operators-regexp
-                          (c-after-special-operator-id lim))))
-           (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
-           (c-add-syntax 'template-args-cont (c-point 'boi) placeholder))
-
-          ;; CASE 5Q: we are at a statement within a macro.
-          (macro-start
-           (c-beginning-of-statement-1 containing-sexp)
-           (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))
-
-          ;; CASE 5M: we are at a topmost continuation line
-          (t
-           (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+        ;; arglist that begins on the previous line.
+        ((and c-recognize-<>-arglists
+              (eq (char-before) ?<)
+              (not (and c-overloadable-operators-regexp
+                        (c-after-special-operator-id lim))))
+         (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+         (c-add-syntax 'template-args-cont (c-point 'boi)))
+
+        ;; CASE 5Q: we are at a statement within a macro.
+        (macro-start
+         (c-beginning-of-statement-1 containing-sexp)
+         (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))
+
+     ;;CASE 5N: We are at a tompmost continuation line and the only
+     ;;preceding items are annotations.
+        ((and (c-major-mode-is 'java-mode)
+              (setq placeholder (point))
+           (c-beginning-of-statement-1)
+           (progn
+                (while (and (c-forward-annotation))
+              (c-forward-syntactic-ws))
+            t)
+          (prog1
+             (>= (point) placeholder)
+             (goto-char placeholder)))
+      (c-add-syntax 'annotation-top-cont (c-point 'boi)))
+
+        ;; CASE 5M: we are at a topmost continuation line
+        (t
+         (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
            (when (c-major-mode-is 'objc-mode)
              (setq placeholder (point))
              (while (and (c-forward-objc-directive)
@@ -9290,43 +9572,20 @@ comment at the start of cc-engine.el for more info."
            (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
           ))
 
-        ;; (CASE 6 has been removed.)
 
-        ;; CASE 19: line is an expression, not a statement, and is directly
-        ;; 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
-        ;; syntactic symbols such as `template-intro',
-        ;; `template-cont-nonempty', etc., and distinguish between them as we
-        ;; do for `arglist-intro' etc. (2009-12-07).
-        ((and c-recognize-<>-arglists
-              (setq containing-< (c-up-list-backward indent-point containing-sexp))
-              (eq (char-after containing-<) ?\<))
-         (setq placeholder (c-point 'boi containing-<))
-         (goto-char containing-sexp)   ; Most nested Lbrace/Lparen (but not
-                                       ; '<') before indent-point.
-         (if (>= (point) placeholder)
-             (progn
-               (forward-char)
-               (skip-chars-forward " \t"))
-           (goto-char placeholder))
-         (c-add-stmt-syntax 'template-args-cont (list containing-<) t
-                            (c-most-enclosing-brace c-state-cache (point))
-                            paren-state))
-                            
+       ;; (CASE 6 has been removed.)
 
-        ;; CASE 7: line is an expression, not a statement.  Most
-        ;; likely we are either in a function prototype or a function
-        ;; call argument list, or a template argument list.
-        ((not (or (and c-special-brace-lists
-                       (save-excursion
-                         (goto-char containing-sexp)
-                         (c-looking-at-special-brace-list)))
-                  (eq (char-after containing-sexp) ?{)
-                  (eq (char-after containing-sexp) ?<)))
-         (cond
+       ;; CASE 7: line is an expression, not a statement.  Most
+       ;; likely we are either in a function prototype or a function
+       ;; call argument list
+       ((not (or (and c-special-brace-lists
+                     (save-excursion
+                       (goto-char containing-sexp)
+                       (c-looking-at-special-brace-list)))
+                (eq (char-after containing-sexp) ?{)))
+       (cond
 
-          ;; CASE 7A: we are looking at the arglist closing paren.
+        ;; CASE 7A: we are looking at the arglist closing paren.
           ;; C.f. case 7F.
           ((memq char-after-ip '(?\) ?\]))
            (goto-char containing-sexp)
@@ -9338,12 +9597,34 @@ comment at the start of cc-engine.el for more info."
                  (skip-chars-forward " \t"))
              (goto-char placeholder))
            (c-add-stmt-syntax 'arglist-close (list containing-sexp) t
-                              (c-most-enclosing-brace paren-state (point))
-                              paren-state))
+                            (c-most-enclosing-brace paren-state (point))
+                            paren-state))
 
-          ;; CASE 7B: Looking at the opening brace of an
-          ;; in-expression block or brace list.  C.f. cases 4, 16A
-          ;; and 17E.
+        ;; CASE 19: line is an expression, not a statement, and is directly
+        ;; 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
+        ;; syntactic symbols such as `template-intro',
+        ;; `template-cont-nonempty', etc., and distinguish between them as we
+        ;; do for `arglist-intro' etc. (2009-12-07).
+        ((and c-recognize-<>-arglists
+            (setq containing-< (c-up-list-backward indent-point containing-sexp))
+            (eq (char-after containing-<) ?\<))
+       (setq placeholder (c-point 'boi containing-<))
+       (goto-char containing-sexp)     ; Most nested Lbrace/Lparen (but not
+                                       ; '<') before indent-point.
+       (if (>= (point) placeholder)
+           (progn
+             (forward-char)
+             (skip-chars-forward " \t"))
+         (goto-char placeholder))
+       (c-add-stmt-syntax 'template-args-cont (list containing-<) t
+                          (c-most-enclosing-brace c-state-cache (point))
+                          paren-state))
+
+        ;; CASE 7B: Looking at the opening brace of an
+        ;; in-expression block or brace list.  C.f. cases 4, 16A
+        ;; and 17E.
           ((and (eq char-after-ip ?{)
                 (progn
                   (setq placeholder (c-inside-bracelist-p (point)
@@ -10065,5 +10346,4 @@ Cannot combine absolute offsets %S and %S in `add' method"
 \f
 (cc-provide 'cc-engine)
 
-;; arch-tag: 149add18-4673-4da5-ac47-6805e4eae089
 ;;; cc-engine.el ends here