Commit 03c45536 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

Merge trivially safe differences from standalone CC-mode.

* lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Don't quote a symbol
just to then pass it to `symbol-value'.
(prog-mode): Provide fallback definition, if needed.
* lisp/progmodes/cc-langs.el: Always load `cl'.  Don't load `cl-lib'.
Remove "cl-" prefix accordingly.
* lisp/progmodes/cc-fonts.el (c-font-lock-invalid-string): Use integerp or
characterp depending on the type of characters.
(c-font-lock-enum-tail): Remove unused var `start'.
* lisp/progmodes/cc-engine.el: Load CL at compile-time.
(c-declare-lang-variables): Use mapcan.
(c-append-to-state-cache): Remove unused var `ce+1'.
(c-parse-state-state): Make buffer-local.
(c-ssb-lit-begin): Remove unused var `pps-end-pos'.
(c-just-after-func-arglist-p): Remove unused var `end'.
* lisp/progmodes/cc-defs.el: Load cc-fix if delete-dups is undefined.
(c-<-as-paren-syntax, c->-as-paren-syntax): Move definition earlier.
(c-make-keywords-re): Use delete-dups.
(c-get-current-file): Avoid file-name-base.
* lisp/progmodes/cc-cmds.el (c-electric-lt-gt): Remove unused var
`close-paren-inserted'.
* lisp/progmodes/cc-awk.el (c-forward-sws): Remove unused declaration.
parent 94ab176a
2014-10-04 Stefan Monnier <monnier@iro.umontreal.ca>
 
Merge trivially safe differences from standalone CC-mode.
* progmodes/cc-mode.el (c-initialize-cc-mode): Don't quote a symbol
just to then pass it to `symbol-value'.
(prog-mode): Provide fallback definition, if needed.
* progmodes/cc-langs.el: Always load `cl'. Don't load `cl-lib'.
Remove "cl-" prefix accordingly.
* progmodes/cc-fonts.el (c-font-lock-invalid-string): Use integerp or
characterp depending on the type of characters.
(c-font-lock-enum-tail): Remove unused var `start'.
* progmodes/cc-engine.el: Load CL at compile-time.
(c-declare-lang-variables): Use mapcan.
(c-append-to-state-cache): Remove unused var `ce+1'.
(c-parse-state-state): Make buffer-local.
(c-ssb-lit-begin): Remove unused var `pps-end-pos'.
(c-just-after-func-arglist-p): Remove unused var `end'.
* progmodes/cc-defs.el: Load cc-fix if delete-dups is undefined.
(c-<-as-paren-syntax, c->-as-paren-syntax): Move definition earlier.
(c-make-keywords-re): Use delete-dups.
(c-get-current-file): Avoid file-name-base.
* progmodes/cc-cmds.el (c-electric-lt-gt): Remove unused var
`close-paren-inserted'.
* progmodes/cc-awk.el (c-forward-sws): Remove unused declaration.
* progmodes/python.el: Avoid building unneeded markers.
(python-font-lock-keywords, python-indent-dedent-line)
(python-fill-paren, python-shell-completion-complete-or-indent):
......
......@@ -61,7 +61,6 @@
(cc-bytecomp-defun c-backward-token-1)
(cc-bytecomp-defun c-beginning-of-statement-1)
(cc-bytecomp-defun c-backward-sws)
(cc-bytecomp-defun c-forward-sws)
(defvar awk-mode-syntax-table
(let ((st (make-syntax-table)))
......
......@@ -1090,7 +1090,7 @@ numeric argument is supplied, or the point is inside a literal."
(interactive "*P")
(let ((c-echo-syntactic-information-p nil)
final-pos close-paren-inserted found-delim case-fold-search)
final-pos found-delim case-fold-search)
(self-insert-command (prefix-numeric-value arg))
(setq final-pos (point))
......
......@@ -86,6 +86,11 @@
font-lock-keywords)))
(cc-load "cc-fix")))
;; XEmacs 21.4 doesn't have `delete-dups'.
(eval-and-compile
(if (and (not (fboundp 'delete-dups))
(not (featurep 'cc-fix)))
(cc-load "cc-fix")))
;;; Variables also used at compile time.
......@@ -913,6 +918,12 @@ MODE is either a mode symbol or a list of mode symbols."
(cc-bytecomp-fboundp 'delete-extent)
(cc-bytecomp-fboundp 'map-extents))))
(defconst c-<-as-paren-syntax '(4 . ?>))
(put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
(defconst c->-as-paren-syntax '(5 . ?<))
(put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax)
;; `c-put-char-property' is complex enough in XEmacs and Emacs < 21 to
;; make it a function.
(defalias 'c-put-char-property-fun
......@@ -1188,9 +1199,6 @@ been put there by c-put-char-property. POINT remains unchanged."
(if (< (point) start)
(goto-char (point-max)))))
(defconst c-<-as-paren-syntax '(4 . ?>))
(put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
(defsubst c-mark-<-as-paren (pos)
;; Mark the "<" character at POS as a template opener using the
;; `syntax-table' property via the `category' property.
......@@ -1201,9 +1209,6 @@ been put there by c-put-char-property. POINT remains unchanged."
;; cheaply. We use this, for instance, in `c-parse-state'.
(c-put-char-property pos 'category 'c-<-as-paren-syntax))
(defconst c->-as-paren-syntax '(5 . ?<))
(put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax)
(defsubst c-mark->-as-paren (pos)
;; Mark the ">" character at POS as an sexp list closer using the
;; syntax-table property.
......@@ -1419,8 +1424,8 @@ Notably, null elements in LIST are ignored."
(defun c-make-keywords-re (adorn list &optional mode)
"Make a regexp that matches all the strings the list.
Duplicates and nil elements in the list are removed. The resulting
regexp may contain zero or more submatch expressions.
Duplicates and nil elements in the list are removed. The
resulting regexp may contain zero or more submatch expressions.
If ADORN is t there will be at least one submatch and the first
surrounds the matched alternative, and the regexp will also not match
......@@ -1438,11 +1443,7 @@ The optional MODE specifies the language to get `c-nonsymbol-key' from
when it's needed. The default is the current language taken from
`c-buffer-is-cc-mode'."
(let (unique)
(dolist (elt list)
(unless (member elt unique)
(push elt unique)))
(setq list (delete nil unique)))
(setq list (delete nil (delete-dups list)))
(if list
(let (re)
......@@ -1638,13 +1639,13 @@ non-nil, a caret is prepended to invert the set."
"support for the `syntax-table' text property "
"is required.")))
;; Find out if generic comment delimiters work.
;; Find out if "\\s!" (generic comment delimiters) work.
(c-safe
(modify-syntax-entry ?x "!")
(if (string-match "\\s!" "x")
(setq list (cons 'gen-comment-delim list))))
;; Find out if generic string delimiters work.
;; Find out if "\\s|" (generic string delimiters) work.
(c-safe
(modify-syntax-entry ?x "|")
(if (string-match "\\s|" "x")
......@@ -1691,7 +1692,8 @@ non-nil, a caret is prepended to invert the set."
(kill-buffer buf))
;; See if `parse-partial-sexp' returns the eighth element.
(if (c-safe (>= (length (save-excursion (parse-partial-sexp (point) (point))))
(if (c-safe (>= (length (save-excursion
(parse-partial-sexp (point) (point))))
10))
(setq list (cons 'pps-extended-state list))
(error (concat
......@@ -1707,9 +1709,8 @@ might be present:
'8-bit 8 bit syntax entry flags (XEmacs style).
'1-bit 1 bit syntax entry flags (Emacs style).
'argumentative-bod-function beginning-of-defun passes ARG through
to a non-null beginning-of-defun-function. It is assumed
the end-of-defun does the same thing.
'argumentative-bod-function beginning-of-defun and end-of-defun pass
ARG through to beginning/end-of-defun-function.
'syntax-properties It works to override the syntax for specific characters
in the buffer with the 'syntax-table property. It's
always set - CC Mode no longer works in emacsen without
......@@ -1803,18 +1804,18 @@ system."
(error "Unknown base mode `%s'" base-mode))
(put mode 'c-fallback-mode base-mode))
(defvar c-lang-constants (make-vector 151 0)
"Obarray used as a cache to keep track of the language constants.
The constants stored are those defined by `c-lang-defconst' and the values
computed by `c-lang-const'. It's mostly used at compile time but it's not
stored in compiled files.
(defvar c-lang-constants (make-vector 151 0))
;; Obarray used as a cache to keep track of the language constants.
;; The constants stored are those defined by `c-lang-defconst' and the values
;; computed by `c-lang-const'. It's mostly used at compile time but it's not
;; stored in compiled files.
The obarray contains all the language constants as symbols. The
value cells hold the evaluated values as alists where each car is
the mode name symbol and the corresponding cdr is the evaluated
value in that mode. The property lists hold the source definitions
and other miscellaneous data. The obarray might also contain
various other symbols, but those don't have any variable bindings.")
;; The obarray contains all the language constants as symbols. The
;; value cells hold the evaluated values as alists where each car is
;; the mode name symbol and the corresponding cdr is the evaluated
;; value in that mode. The property lists hold the source definitions
;; and other miscellaneous data. The obarray might also contain
;; various other symbols, but those don't have any variable bindings.
(defvar c-lang-const-expansion nil)
......@@ -1831,7 +1832,9 @@ various other symbols, but those don't have any variable bindings.")
(t
;; Being evaluated interactively.
(buffer-file-name)))))
(and file (file-name-base file))))
(and file
(file-name-sans-extension
(file-name-nondirectory file)))))
(defmacro c-lang-defconst-eval-immediately (form)
"Can be used inside a VAL in `c-lang-defconst' to evaluate FORM
......
......@@ -147,18 +147,19 @@
(cc-require-when-compile 'cc-langs)
(cc-require 'cc-vars)
(eval-when-compile (require 'cl))
;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
(defmacro c-declare-lang-variables ()
`(progn
,@(apply 'nconc
(mapcar (lambda (init)
`(,(if (elt init 2)
`(defvar ,(car init) nil ,(elt init 2))
`(defvar ,(car init) nil))
(make-variable-buffer-local ',(car init))))
(cdr c-lang-variable-inits)))))
,@(mapcan (lambda (init)
`(,(if (elt init 2)
`(defvar ,(car init) nil ,(elt init 2))
`(defvar ,(car init) nil))
(make-variable-buffer-local ',(car init))))
(cdr c-lang-variable-inits))))
(c-declare-lang-variables)
......@@ -826,7 +827,6 @@ comment at the start of cc-engine.el for more info."
;; Record this as the first token if not starting inside it.
(setq tok start))
;; The following while loop goes back one sexp (balanced parens,
;; etc. with contents, or symbol or suchlike) each iteration. This
;; movement is accomplished with a call to c-backward-sexp approx 170
......@@ -2159,7 +2159,6 @@ comment at the start of cc-engine.el for more info."
;; the middle of the desert, as long as it is not within a brace pair
;; recorded in `c-state-cache' or a paren/bracket pair.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; We maintain a simple cache of positions which aren't in a literal, so as to
;; speed up testing for non-literality.
......@@ -2780,7 +2779,7 @@ comment at the start of cc-engine.el for more info."
paren+1 ; Pos after some opening or closing paren.
paren+1s ; A list of `paren+1's; used to determine a
; good-pos.
bra+1 ce+1 ; just after L/R bra-ces.
bra+1 ; just after L bra-ce.
bra+1s ; list of OLD values of bra+1.
mstart) ; start of a macro.
......@@ -3392,6 +3391,7 @@ comment at the start of cc-engine.el for more info."
(defvar c-parse-state-point nil)
(defvar c-parse-state-state nil)
(make-variable-buffer-local 'c-parse-state-state)
(defun c-record-parse-state-state ()
(setq c-parse-state-point (point))
(setq c-parse-state-state
......@@ -4166,7 +4166,7 @@ comment at the start of cc-engine.el for more info."
;; Use `parse-partial-sexp' from a safe position down to the point to check
;; if it's outside comments and strings.
(save-excursion
(let ((pos (point)) safe-pos state pps-end-pos)
(let ((pos (point)) safe-pos state)
;; Pick a safe position as close to the point as possible.
;;
;; FIXME: Consult `syntax-ppss' here if our cache doesn't give a good
......@@ -4860,14 +4860,17 @@ comment at the start of cc-engine.el for more info."
;; it should return non-nil to ensure that the next search will find them.
;;
;; Such a spot is:
;; o The first token after bob.
;; o The first token after the end of submatch 1 in
;; `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 occurrence of the
;; `c-type' text property with the value `c-decl-end', provided
;; `c-type-decl-end-used' is set.
;; o The first token after bob.
;; o The first token after the end of submatch 1 in
;; `c-decl-prefix-or-start-re' when that submatch matches. This
;; submatch is typically a (L or R) brace or paren, a ;, or a ,.
;; o The start of each `c-decl-prefix-or-start-re' match when
;; submatch 1 doesn't match. This is, for example, the keyword
;; "class" in Pike.
;; o The start of a previously recognized declaration; "recognized"
;; means that the last char of the previous token has a `c-type'
;; text property with the value `c-decl-end'; this only holds
;; when `c-type-decl-end-used' is set.
;;
;; Only a spot that match CFD-DECL-RE and whose face is in the
;; CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The face
......@@ -4899,7 +4902,7 @@ comment at the start of cc-engine.el for more info."
;;
;; This function might do hidden buffer changes.
(let ((cfd-start-pos (point))
(let ((cfd-start-pos (point)) ; never changed
(cfd-buffer-end (point-max))
;; The end of the token preceding the decl spot last found
;; with `c-decl-prefix-or-start-re'. `cfd-limit' if there's
......@@ -4938,10 +4941,20 @@ comment at the start of cc-engine.el for more info."
;; statement or declaration, which is earlier than the first
;; returned match.
;; This `cond' moves back over any literals or macros. It has special
;; handling for when the region being searched is entirely within a
;; macro. It sets `cfd-continue-pos' (unless we've reached
;; `cfd-limit').
(cond
;; First we need to move to a syntactically relevant position.
;; Begin by backing out of comment or string literals.
;;
;; This arm of the cond actually triggers if we're in a literal,
;; and cfd-limit is at most at BONL.
((and
;; This arm of the `and' moves backwards out of a literal when
;; the face at point is a literal face. In this case, its value
;; is always non-nil.
(when (c-got-face-at (point) c-literal-faces)
;; Try to use the faces to back up to the start of the
;; literal. FIXME: What if the point is on a declaration
......@@ -4970,7 +4983,7 @@ comment at the start of cc-engine.el for more info."
(let ((range (c-literal-limits)))
(if range (goto-char (car range)))))
(setq start-in-literal (point)))
(setq start-in-literal (point))) ; end of `and' arm.
;; The start is in a literal. If the limit is in the same
;; one we don't have to find a syntactic position etc. We
......@@ -4985,18 +4998,18 @@ comment at the start of cc-engine.el for more info."
(point) 'face nil cfd-limit))
(and (< (point) cfd-limit)
(c-got-face-at (point) c-literal-faces))))
(= (point) cfd-limit)))
(= (point) cfd-limit))) ; end of `cond' arm condition
;; Completely inside a literal. Set up variables to trig the
;; (< cfd-continue-pos cfd-start-pos) case below and it'll
;; find a suitable start position.
(setq cfd-continue-pos start-in-literal))
(setq cfd-continue-pos start-in-literal)) ; end of `cond' arm
;; Check if the region might be completely inside a macro, to
;; optimize that like the completely-inside-literal above.
((save-excursion
(and (= (forward-line 1) 0)
(bolp) ; forward-line has funny behavior at eob.
(bolp) ; forward-line has funny behavior at eob.
(>= (point) cfd-limit)
(progn (backward-char)
(eq (char-before) ?\\))))
......@@ -5006,6 +5019,8 @@ comment at the start of cc-engine.el for more info."
(setq cfd-continue-pos (1- cfd-start-pos)
start-in-macro t))
;; The default arm of the `cond' moves back over any macro we're in
;; and over any syntactic WS. It sets `c-find-decl-syntactic-pos'.
(t
;; Back out of any macro so we don't miss any declaration
;; that could follow after it.
......@@ -5052,10 +5067,10 @@ comment at the start of cc-engine.el for more info."
(< (point) cfd-limit))
;; Do an initial search now. In the bob case above it's
;; only done to search for a `c-decl-end' spot.
(c-find-decl-prefix-search))
(c-find-decl-prefix-search)) ; sets cfd-continue-pos
(setq c-find-decl-match-pos (and (< cfd-match-pos cfd-start-pos)
cfd-match-pos)))))
cfd-match-pos))))) ; end of `cond'
;; Advance `cfd-continue-pos' if it's before the start position.
;; The closest continue position that might have effect at or
......@@ -5114,7 +5129,7 @@ comment at the start of cc-engine.el for more info."
;; `cfd-match-pos' so we can continue at the start position.
;; (Note that we don't get here if the first match is below
;; it.)
(goto-char cfd-start-pos)))
(goto-char cfd-start-pos))) ; end of `cond'
;; Delete found matches if they are before our new continue
;; position, so that `c-find-decl-prefix-search' won't back up
......@@ -5123,7 +5138,7 @@ comment at the start of cc-engine.el for more info."
(when (and cfd-re-match (< cfd-re-match cfd-continue-pos))
(setq cfd-re-match nil))
(when (and cfd-prop-match (< cfd-prop-match cfd-continue-pos))
(setq cfd-prop-match nil)))
(setq cfd-prop-match nil))) ; end of `when'
(if syntactic-pos
;; This is the normal case and we got a proper syntactic
......@@ -5144,9 +5159,10 @@ comment at the start of cc-engine.el for more info."
;; good start position for the search, so do it.
(c-find-decl-prefix-search)))
;; Now loop. Round what? (ACM, 2006/7/5). We already got the first match.
;; Now loop, one decl spot per iteration. We already have the first
;; match in `cfd-match-pos'.
(while (progn
;; Go foward over "false matches", one per iteration.
(while (and
(< cfd-match-pos cfd-limit)
......@@ -5187,10 +5203,10 @@ comment at the start of cc-engine.el for more info."
(goto-char cfd-continue-pos)
t)))
(< (point) cfd-limit))
(c-find-decl-prefix-search))
(< (point) cfd-limit)) ; end of "false matches" condition
(c-find-decl-prefix-search)) ; end of "false matches" loop
(< (point) cfd-limit))
(< (point) cfd-limit)) ; end of condition for "decl-spot" while
(when (and
(>= (point) cfd-start-pos)
......@@ -5218,7 +5234,7 @@ comment at the start of cc-engine.el for more info."
;; The matched token was the last thing in the macro,
;; so the whole match is bogus.
(setq cfd-macro-end 0)
nil))))
nil)))) ; end of when condition
(c-debug-put-decl-spot-faces cfd-match-pos (point))
(if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0))
......@@ -5531,8 +5547,6 @@ comment at the start of cc-engine.el for more info."
(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
;; c-recognize-<>-arglists' is set. It ensures that no "<" or ">"
......@@ -5867,7 +5881,6 @@ comment at the start of cc-engine.el for more info."
;; Recursive part of `c-forward-<>-arglist'.
;;
;; This function might do hidden buffer changes.
(let ((start (point)) res pos tmp
;; Cover this so that any recorded found type ranges are
;; automatically lost if it turns out to not be an angle
......@@ -5993,7 +6006,6 @@ comment at the start of cc-engine.el for more info."
(c-keyword-member
(c-keyword-sym (match-string 1))
'c-<>-type-kwds)))))))
;; It was an angle bracket arglist.
(setq c-record-found-types subres)
......@@ -7100,36 +7112,35 @@ comment at the start of cc-engine.el for more info."
(catch 'at-decl-or-cast
;; CASE 1
(when (> paren-depth 0)
;; Encountered something inside parens that isn't matched by
;; the `c-type-decl-*' regexps, so it's not a type decl
;; expression. Try to skip out to the same paren depth to
;; not confuse the cast check below.
(c-safe (goto-char (scan-lists (point) 1 paren-depth)))
;; 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 at-decl-end
(looking-at (cond ((eq context '<>) "[,>]")
(context "[,\)]")
(t "[,;]"))))
;; 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
;; signs before less certain ones.
(if got-identifier
(progn
;; CASE 2
(when (and (or at-type maybe-typeless)
(not (or got-prefix got-parens)))
;; Got another identifier directly after the type, so it's a
;; declaration.
(throw 'at-decl-or-cast t))
(when (> paren-depth 0)
;; Encountered something inside parens that isn't matched by
;; the `c-type-decl-*' regexps, so it's not a type decl
;; expression. Try to skip out to the same paren depth to
;; not confuse the cast check below.
(c-safe (goto-char (scan-lists (point) 1 paren-depth)))
;; 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 at-decl-end
(looking-at (cond ((eq context '<>) "[,>]")
(context "[,\)]")
(t "[,;]"))))
;; 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
;; signs before less certain ones.
(if got-identifier
(progn
;; CASE 2
(when (and (or at-type maybe-typeless)
(not (or got-prefix got-parens)))
;; Got another identifier directly after the type, so it's a
;; declaration.
(throw 'at-decl-or-cast t))
(when (and got-parens
(not got-prefix)
......@@ -7151,9 +7162,9 @@ comment at the start of cc-engine.el for more info."
(c-fdoc-shift-type-backward)))
;; Found no identifier.
(if backup-at-type
(progn
(if backup-at-type
(progn
;; CASE 3
(when (= (point) start)
......@@ -7176,251 +7187,251 @@ comment at the start of cc-engine.el for more info."
(setq backup-if-not-cast t)
(throw 'at-decl-or-cast t)))
;; CASE 4
(when (and got-suffix
(not got-prefix)
(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
;; CASE 4
(when (and got-suffix
(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
<