- (not got-suffix)
- (not (eq at-type t)))
- ;; Shift the type backward in the case that there's a
- ;; single identifier inside parens. That can only
- ;; occur in K&R style function declarations so it's
- ;; more likely that it really is a function call.
- ;; Therefore we only do this after
- ;; `c-after-suffixed-type-decl-key' has matched.
- (progn (c-fdoc-shift-type-backward) t)
- got-suffix-after-parens))
- ;; A declaration according to `c-after-suffixed-type-decl-key'.
- (throw 'at-decl-or-cast t))
-
- ;; CASE 12
- (when (and (or got-prefix (not got-parens))
- (memq at-type '(t known)))
- ;; It's a declaration if a known type precedes it and it can't be a
- ;; function call.
- (throw 'at-decl-or-cast t))
-
- ;; If we get here we can't tell if this is a type decl or a normal
- ;; expression by looking at it alone. (That's under the assumption
- ;; that normal expressions always can look like type decl expressions,
- ;; which isn't really true but the cases where it doesn't hold are so
- ;; uncommon (e.g. some placements of "const" in C++) it's not worth
- ;; the effort to look for them.)
+ (not got-parens))
+ ;; Got a plain list of identifiers followed by some suffix.
+ ;; If this isn't a cast then the last identifier probably is
+ ;; the declared one and we should back up to the previous
+ ;; type.
+ (setq backup-if-not-cast t)
+ (throw 'at-decl-or-cast t)))
+
+ ;; CASE 5
+ (when (eq at-type t)
+ ;; If the type is known we know that there can't be any
+ ;; identifier somewhere else, and it's only in declarations in
+ ;; e.g. function prototypes and in casts that the identifier may
+ ;; be left out.
+ (throw 'at-decl-or-cast t))
+
+ (when (= (point) start)
+ ;; Only got a single identifier (parsed as a type so far).
+ ;; CASE 6
+ (if (and
+ ;; Check that the identifier isn't at the start of an
+ ;; expression.
+ at-decl-end
+ (cond
+ ((eq context 'decl)
+ ;; 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
+ ;; (primitive types are handled above).
+ (or (and (not c-recognize-knr-p)
+ (not c-recognize-paren-inits))
+ (memq at-type '(known found))))
+ ((eq context '<>)
+ ;; Inside a template arglist. Accept known and found
+ ;; types; other identifiers could just as well be
+ ;; constants in C++.
+ (memq at-type '(known found)))))
+ (throw 'at-decl-or-cast t)
+ ;; CASE 7
+ ;; Can't be a valid declaration or cast, but if we've found a
+ ;; specifier it can't be anything else either, so treat it as
+ ;; an invalid/unfinished declaration or cast.
+ (throw 'at-decl-or-cast at-decl-or-cast))))
+
+ (if (and got-parens
+ (not got-prefix)
+ (not context)
+ (not (eq at-type t))
+ (or backup-at-type
+ maybe-typeless
+ backup-maybe-typeless
+ (when c-recognize-typeless-decls
+ (or (not got-suffix)
+ (not (looking-at
+ 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
+ ;; "backtracking" done inside the `c-type-decl-suffix-key' loop
+ ;; above.
+ ;;
+ ;; Exception: In addition to the conditions in that
+ ;; "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
+ ;; 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.
+ (c-fdoc-shift-type-backward)
+
+ ;; Still no identifier.
+ ;; CASE 8
+ (when (and got-prefix (or got-parens got-suffix))
+ ;; Require `got-prefix' together with either `got-parens' or
+ ;; `got-suffix' to recognize it as an abstract declarator:
+ ;; `got-parens' only is probably an empty function call.
+ ;; `got-suffix' only can build an ordinary expression together
+ ;; with the preceding identifier which we've taken as a type.
+ ;; We could actually accept on `got-prefix' only, but that can
+ ;; easily occur temporarily while writing an expression so we
+ ;; avoid that case anyway. We could do a better job if we knew
+ ;; the point when the fontification was invoked.
+ (throw 'at-decl-or-cast t))
+
+ ;; CASE 9
+ (when (and at-type
+ (not got-prefix)
+ (not got-parens)
+ got-suffix-after-parens
+ (eq (char-after got-suffix-after-parens) ?\())
+ ;; Got a type, no declarator but a paren suffix. I.e. it's a
+ ;; normal function call after all (or perhaps a C++ style object
+ ;; instantiation expression).
+ (throw 'at-decl-or-cast nil))))
+
+ ;; CASE 10
+ (when at-decl-or-cast
+ ;; By now we've located the type in the declaration that we know
+ ;; we're in.
+ (throw 'at-decl-or-cast t))
+
+ ;; CASE 11
+ (when (and got-identifier
+ (not context)
+ (looking-at c-after-suffixed-type-decl-key)
+ (if (and got-parens
+ (not got-prefix)
+ (not got-suffix)
+ (not (eq at-type t)))
+ ;; Shift the type backward in the case that there's a
+ ;; single identifier inside parens. That can only
+ ;; occur in K&R style function declarations so it's
+ ;; more likely that it really is a function call.
+ ;; Therefore we only do this after
+ ;; `c-after-suffixed-type-decl-key' has matched.
+ (progn (c-fdoc-shift-type-backward) t)
+ got-suffix-after-parens))
+ ;; A declaration according to `c-after-suffixed-type-decl-key'.
+ (throw 'at-decl-or-cast t))
+
+ ;; CASE 12
+ (when (and (or got-prefix (not got-parens))
+ (memq at-type '(t known)))
+ ;; It's a declaration if a known type precedes it and it can't be a
+ ;; function call.
+ (throw 'at-decl-or-cast t))
+
+ ;; If we get here we can't tell if this is a type decl or a normal
+ ;; expression by looking at it alone. (That's under the assumption
+ ;; that normal expressions always can look like type decl expressions,
+ ;; which isn't really true but the cases where it doesn't hold are so
+ ;; uncommon (e.g. some placements of "const" in C++) it's not worth
+ ;; the effort to look for them.)