Function: c-font-lock-declarations
c-font-lock-declarations is a byte-compiled function defined in
cc-fonts.el.gz.
Signature
(c-font-lock-declarations LIMIT)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-fonts.el.gz
(defun c-font-lock-declarations (limit)
;; Fontify all the declarations, casts and labels from the point to LIMIT.
;; Assumes that strings and comments have been fontified already.
;;
;; This function will be called from font-lock for a region bounded by POINT
;; and LIMIT, as though it were to identify a keyword for
;; font-lock-keyword-face. It always returns NIL to inhibit this and
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; Fontification".
;;
;; This function might do hidden buffer changes.
;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(save-restriction
(let (;; The position where `c-find-decl-spots' last stopped.
start-pos
;; o - 'decl if we're in an arglist containing declarations
;; (but if `c-recognize-paren-inits' is set it might also be
;; an initializer arglist);
;; o - '<> if the arglist is of angle bracket type;
;; o - 'arglist if it's some other arglist;
;; o - nil, if not in an arglist at all. This includes the
;; parenthesized condition which follows "if", "while", etc.
context
;; A list of starting positions of possible type declarations, or of
;; the typedef preceding one, if any.
last-cast-end
;; The result from `c-forward-decl-or-cast-1'.
decl-or-cast
;; The maximum of the end positions of all the checked type
;; decl expressions in the successfully identified
;; declarations. The position might be either before or
;; after the syntactic whitespace following the last token
;; in the type decl expression.
(max-type-decl-end 0)
;; Same as `max-type-decl-*', but used when we're before
;; `token-pos'.
(max-type-decl-end-before-token 0)
;; End of <..> construct which has had c-<>-arg-sep c-type
;; properties set within it.
(max-<>-end 0)
;; Set according to the context to direct the heuristics for
;; recognizing C++ templates.
c-restricted-<>-arglists
;; Turn on recording of identifier ranges in
;; `c-forward-decl-or-cast-1' and `c-forward-label' for
;; later fontification.
(c-record-type-identifiers t)
label-type
c-record-ref-identifiers
;; Make `c-forward-type' calls mark up template arglists if
;; it finds any. That's necessary so that we later will
;; stop inside them to fontify types there.
(c-parse-and-markup-<>-arglists t)
;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties)))
list-bounds)
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
;; time. That is however annoying during editing, e.g. the following is
;; a common situation while the first line is being written:
;;
;; my_variable
;; some_other_variable = 0;
;;
;; font-lock will put the limit at the beginning of the second line
;; here, and if we go past it we'll fontify "my_variable" as a type and
;; "some_other_variable" as an identifier, and the latter will not
;; correct itself until the second line is changed. To avoid that we
;; narrow to the limit if the region to fontify is a single line.
(if (<= limit (c-point 'bonl))
(narrow-to-region
(point-min)
(save-excursion
;; Narrow after any operator chars following the limit though,
;; since those characters can be useful in recognizing a
;; declaration (in particular the '{' that opens a function body
;; after the header).
(goto-char limit)
(skip-chars-forward c-nonsymbol-chars)
(point))))
(c-find-decl-spots
limit
c-decl-start-re
(eval c-maybe-decl-faces)
(lambda (match-pos inside-macro &optional toplev)
;; Note to maintainers: don't use `limit' inside this lambda form;
;; c-find-decl-spots sometimes narrows to less than `limit'.
(setq start-pos (point))
(when
;; The result of the form below is true when we don't recognize a
;; declaration or cast, and we don't recognize a "non-decl",
;; typically a brace list.
(if (or (and (eq (get-text-property (point) 'face)
'font-lock-keyword-face)
(looking-at c-not-decl-init-keywords))
(and c-macro-with-semi-re
(looking-at c-macro-with-semi-re))) ; 2008-11-04
;; Don't do anything more if we're looking at a keyword that
;; can't start a declaration.
t
;; Set `context' and `c-restricted-<>-arglists'. Look for
;; "<" for the sake of C++-style template arglists.
;; Ignore "(" when it's part of a control flow construct
;; (e.g. "for (").
(let ((got-context
(c-get-fontification-context
match-pos
(< match-pos (if inside-macro
max-type-decl-end-before-token
max-type-decl-end))
toplev)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
;; Check we haven't missed a preceding "typedef".
(when (not (looking-at c-typedef-key))
(c-backward-syntactic-ws
(max (- (point) 1000) (point-min)))
(c-backward-token-2)
(or (looking-at c-typedef-key)
(goto-char start-pos)))
;; In QT, "more" is an irritating keyword that expands to nothing.
;; We skip over it to prevent recognition of "more slots: <symbol>"
;; as a bitfield declaration.
(when (and (c-major-mode-is 'c++-mode)
(looking-at "\\_<\\(more\\)\\_>"))
(goto-char (match-end 1))
(c-forward-syntactic-ws))
;; Now analyze the construct.
(cond
((eq context 'not-decl)
(setq decl-or-cast nil)
(if (c-syntactic-re-search-forward
"," (min limit (point-max)) 'at-limit t)
(c-put-char-property (1- (point)) 'c-type 'c-not-decl))
nil)
((eq context 'generic)
(c-font-lock-c11-generic-clause))
;; K&R parameters.
((and
c-recognize-knr-p
(or toplev inside-macro)
(eq context 'decl)
(setq list-bounds (c-in-id-arglist))
(save-excursion
(goto-char (car list-bounds))
(and (zerop (c-backward-token-2))
(eq (point) (c-on-identifier))))
(save-excursion
(goto-char (cdr list-bounds))
(c-forward-syntactic-ws)
(not (memq (char-after) '(?\; ?{ ?\? ?: ?\,)))))
;; Nothing to fontify.
(goto-char (cdr list-bounds)))
(t
(setq decl-or-cast
(c-forward-decl-or-cast-1
match-pos context last-cast-end inside-macro))
;; Ensure that c-<>-arg-sep c-type properties are in place on the
;; commas separating the arguments inside template/generic <..>s.
(when (and (eq (char-before match-pos) ?<)
(> match-pos max-<>-end))
(save-excursion
(goto-char match-pos)
(c-backward-token-2)
(if (and
(eq (char-after) ?<)
(let ((c-restricted-<>-arglists
(save-excursion
(c-backward-token-2)
(and
(not (looking-at c-opt-<>-sexp-key))
(progn
(c-backward-syntactic-ws
(max (- (point) 1000) (point-min)))
(memq (char-before) '(?\( ?,)))
(not (eq (c-get-char-property (1- (point))
'c-type)
'c-decl-arg-start))))))
(c-forward-<>-arglist nil)))
(setq max-<>-end (point)))))
(cond
((eq decl-or-cast 'cast)
;; Save the position after the previous cast so we can feed
;; it to `c-forward-decl-or-cast-1' in the next round. That
;; helps it discover cast chains like "(a) (b) c".
(setq last-cast-end (point))
(c-fontify-recorded-types-and-refs)
nil)
(decl-or-cast
;; We've found a declaration.
;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
;; under the assumption that we're after the first type decl
;; expression in the declaration now. That's not really true;
;; we could also be after a parenthesized initializer
;; expression in C++, but this is only used as a last resort
;; to slant ambiguous expression/declarations, and overall
;; it's worth the risk to occasionally fontify an expression
;; as a declaration in an initializer expression compared to
;; getting ambiguous things in normal function prototypes
;; fontified as expressions.
(if inside-macro
(when (> (point) max-type-decl-end-before-token)
(setq max-type-decl-end-before-token (point)))
(when (> (point) max-type-decl-end)
(setq max-type-decl-end (point))))
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast match-pos
context
(or toplev (nth 4 decl-or-cast))))
(t t)))))
;; It was a false alarm. Check if we're in a label (or other
;; construct with `:' except bitfield) instead.
(goto-char start-pos)
(when (setq label-type (c-forward-label t match-pos nil))
;; Can't use `c-fontify-types-and-refs' here since we
;; use the label face at times.
(cond ((eq label-type 'goto-target)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
c-label-face-name))
((eq label-type 'qt-1kwd-colon)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
'font-lock-keyword-face))
((eq label-type 'qt-2kwds-colon)
(mapc
(lambda (kwd)
(c-put-font-lock-face (car kwd) (cdr kwd)
'font-lock-keyword-face))
c-record-ref-identifiers)))
(setq c-record-ref-identifiers nil)
;; `c-forward-label' has probably added a `c-decl-end'
;; marker, so return t to `c-find-decl-spots' to signal
;; that.
t))))
nil))))