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))))