+ (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights)
+ ;; This function makes a byte compiled function that first moves back
+ ;; to the beginning of the current declaration (if any), then searches
+ ;; forward for matcher elements (as in `font-lock-keywords') and
+ ;; fontifies them.
+ ;;
+ ;; The motivation for moving back to the declaration start is to
+ ;; establish a context for the current text when, e.g., a character
+ ;; is typed on a C++ inheritance continuation line, or a jit-lock
+ ;; chunk starts there.
+ ;;
+ ;; The new function works much like a matcher element in
+ ;; `font-lock-keywords'. It cuts out a little bit of the overhead
+ ;; compared to a real matcher. The main reason is however to pass the
+ ;; real search limit to the anchored matcher(s), since most (if not
+ ;; all) font-lock implementations arbitrarily limit anchored matchers
+ ;; to the same line, and also to insulate against various other
+ ;; irritating differences between the different (X)Emacs font-lock
+ ;; packages.
+ ;;
+ ;; REGEXP is the matcher, which must be a regexp. Only matches
+ ;; where the beginning is outside any comment or string literal are
+ ;; significant.
+ ;;
+ ;; HIGHLIGHTS is a list of highlight specs, just like in
+ ;; `font-lock-keywords', with these limitations: The face is always
+ ;; overridden (no big disadvantage, since hits in comments etc are
+ ;; filtered anyway), there is no "laxmatch", and an anchored matcher
+ ;; is always a form which must do all the fontification directly.
+ ;; `limit' is a variable bound to the real limit in the context of
+ ;; the anchored matcher forms.
+ ;;
+ ;; This function does not do any hidden buffer changes, but the
+ ;; generated functions will. (They are however used in places
+ ;; covered by the font-lock context.)
+
+ ;; Note: Replace `byte-compile' with `eval' to debug the generated
+ ;; lambda more easily.
+ (byte-compile
+ `(lambda (limit)
+ (let ( ;; 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))))
+ (goto-char
+ (let ((here (point)))
+ (if (eq (car (c-beginning-of-decl-1)) 'same)
+ (point)
+ here)))
+ ,(c-make-font-lock-search-form regexp highlights))
+ nil)))
+
+ (defun c-make-font-lock-context-search-function (normal &rest state-stanzas)
+ ;; This function makes a byte compiled function that works much like
+ ;; a matcher element in `font-lock-keywords', with the following
+ ;; enhancement: the generated function will test for particular "font
+ ;; lock contexts" at the start of the region, i.e. is this point in
+ ;; the middle of some particular construct? if so the generated
+ ;; function will first fontify the tail of the construct, before
+ ;; going into the main loop and fontify full constructs up to limit.
+ ;;
+ ;; The generated function takes one parameter called `limit', and
+ ;; will fontify the region between POINT and LIMIT.
+ ;;
+ ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is
+ ;; used to fontify the "regular" bit of the region.
+ ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP
+ ;; HIGHLIGHTS), each element coding one possible font lock context.
+
+ ;; o - REGEXP is a font-lock regular expression (NOT a function),
+ ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined
+ ;; on page "Search-based Fontification" in the elisp manual. As
+ ;; yet (2009-06), they must have OVERRIDE set, and may not have
+ ;; LAXMATCH set.
+ ;;
+ ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is
+ ;; not quoted.
+ ;; o - LIM is a lisp form whose evaluation will yield the limit
+ ;; position in the buffer for fontification by this stanza.
+ ;;
+ ;; This function does not do any hidden buffer changes, but the
+ ;; generated functions will. (They are however used in places
+ ;; covered by the font-lock context.)
+ ;;
+ ;; Note: Replace `byte-compile' with `eval' to debug the generated
+ ;; lambda more easily.
+ (byte-compile
+ `(lambda (limit)
+ (let ( ;; 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))))
+ ,@(mapcar
+ (lambda (stanza)
+ (let ((state (car stanza))
+ (lim (nth 1 stanza))
+ (regexp (nth 2 stanza))
+ (highlights (cdr (cddr stanza))))
+ `(if (eq c-font-lock-context ',state)
+ (let ((limit ,lim))
+ ,(c-make-font-lock-search-form
+ regexp highlights)))))
+ state-stanzas)
+ ,(c-make-font-lock-search-form (car normal) (cdr normal))
+ nil))))
+