1;;; cc-fonts.el --- font lock support for CC Mode -*- lexical-binding: t -*-
2
3;; Copyright (C) 2002-2021 Free Software Foundation, Inc.
4
5;; Authors:    2003- Alan Mackenzie
6;;             2002- Martin Stjernholm
7;; Maintainer: bug-cc-mode@gnu.org
8;; Created:    07-Jan-2002
9;; Keywords:   c languages
10;; Package:    cc-mode
11
12;; This file is part of GNU Emacs.
13
14;; GNU Emacs is free software: you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
26
27;;; Commentary:
28
29;; Some comments on the use of faces:
30;;
31;; o  `c-label-face-name' is either `font-lock-constant-face' (in
32;;    Emacs), or `font-lock-reference-face'.
33;;
34;; o  `c-constant-face-name', `c-reference-face-name' and
35;;    `c-doc-markup-face-name' are essentially set up like
36;;    `c-label-face-name'.
37;;
38;; o  `c-preprocessor-face-name' is `font-lock-preprocessor-face' in
39;;    XEmacs and - in lack of a closer equivalent -
40;;    `font-lock-builtin-face' or `font-lock-reference-face' in Emacs.
41;;
42;; o  `c-doc-face-name' is `font-lock-doc-string-face' in XEmacs,
43;;    `font-lock-doc-face' in Emacs 21 and later, or
44;;    `font-lock-comment-face' in older Emacs (that since source
45;;    documentation are actually comments in these languages, as opposed
46;;    to elisp).
47;;
48;; TBD: We should probably provide real faces for the above uses and
49;; instead initialize them from the standard faces.
50
51;;; Code:
52
53;; The faces that already have been put onto the text is tested in
54;; various places to direct further fontifications.  For this to work,
55;; the following assumptions regarding the faces must hold (apart from
56;; the dependencies on the font locking order):
57;;
58;; o  `font-lock-comment-face' and the face in `c-doc-face-name' is
59;;    not used in anything but comments.
60;; o  If any face (e.g. `c-doc-markup-face-name') but those above is
61;;    used in comments, it doesn't replace them.
62;; o  `font-lock-string-face' is not used in anything but string
63;;    literals (single or double quoted).
64;; o  `font-lock-keyword-face' and the face in `c-label-face-name' are
65;;    never overlaid with other faces.
66
67(eval-when-compile
68  (let ((load-path
69	 (if (and (boundp 'byte-compile-dest-file)
70		  (stringp byte-compile-dest-file))
71	     (cons (file-name-directory byte-compile-dest-file) load-path)
72	   load-path)))
73    (load "cc-bytecomp" nil t)))
74
75(cc-require 'cc-defs)
76(cc-require-when-compile 'cc-langs)
77(cc-require 'cc-vars)
78(cc-require 'cc-engine)
79
80;; Avoid repeated loading through the eval-after-load directive in
81;; cc-mode.el.
82(provide 'cc-fonts)
83
84(cc-external-require 'font-lock)
85
86(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only.
87
88;; Need to declare these local symbols during compilation since
89;; they're referenced from lambdas in `byte-compile' calls that are
90;; executed at compile time.  They don't need to have the proper
91;; definitions, though, since the generated functions aren't called
92;; during compilation.
93(cc-bytecomp-defvar c-preprocessor-face-name)
94(cc-bytecomp-defvar c-reference-face-name)
95(cc-bytecomp-defvar c-block-comment-flag)
96(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
97(cc-bytecomp-defun c-font-lock-declarators)
98(cc-bytecomp-defun c-font-lock-objc-method)
99(cc-bytecomp-defun c-font-lock-invalid-string)
100(cc-bytecomp-defun c-font-lock-fontify-region)
101
102
103;; Note that font-lock in XEmacs doesn't expand face names as
104;; variables, so we have to use the (eval . FORM) in the font lock
105;; matchers wherever we use these alias variables.
106
107(defconst c-preprocessor-face-name
108  (cond ((c-face-name-p 'font-lock-preprocessor-face)
109	 ;; XEmacs has a font-lock-preprocessor-face.
110	 'font-lock-preprocessor-face)
111	((c-face-name-p 'font-lock-builtin-face)
112	 ;; In Emacs font-lock-builtin-face has traditionally been
113	 ;; used for preprocessor directives.
114	 'font-lock-builtin-face)
115	(t
116	 'font-lock-reference-face)))
117
118(cc-bytecomp-defvar font-lock-constant-face)
119
120(defconst c-label-face-name
121  (cond ((c-face-name-p 'font-lock-label-face)
122	 ;; If it happens to occur in the future.  (Well, the more
123	 ;; pragmatic reason is to get unique faces for the test
124	 ;; suite.)
125	 'font-lock-label-face)
126	((and (c-face-name-p 'font-lock-constant-face)
127	      (eq font-lock-constant-face 'font-lock-constant-face))
128	 ;; Test both if font-lock-constant-face exists and that it's
129	 ;; not an alias for something else.  This is important since
130	 ;; we compare already set faces in various places.
131	 'font-lock-constant-face)
132	(t
133	 'font-lock-reference-face)))
134
135(defconst c-constant-face-name
136  (if (and (c-face-name-p 'font-lock-constant-face)
137	   (eq font-lock-constant-face 'font-lock-constant-face))
138      ;; This doesn't exist in some earlier versions of XEmacs 21.
139      'font-lock-constant-face
140    c-label-face-name))
141
142(defconst c-reference-face-name
143  (with-no-warnings
144   (if (and (c-face-name-p 'font-lock-reference-face)
145	    (eq font-lock-reference-face 'font-lock-reference-face))
146       ;; This is considered obsolete in Emacs, but it still maps well
147       ;; to this use.  (Another reason to do this is to get unique
148       ;; faces for the test suite.)
149       'font-lock-reference-face
150     c-label-face-name)))
151
152;; This should not mapped to a face that also is used to fontify things
153;; that aren't comments or string literals.
154(defconst c-doc-face-name
155  (cond ((c-face-name-p 'font-lock-doc-string-face)
156	 ;; XEmacs.
157	 'font-lock-doc-string-face)
158	((c-face-name-p 'font-lock-doc-face)
159	 ;; Emacs 21 and later.
160	 'font-lock-doc-face)
161	(t
162	 'font-lock-comment-face)))
163
164(defconst c-doc-markup-face-name
165  (if (c-face-name-p 'font-lock-doc-markup-face)
166	 ;; If it happens to occur in the future.  (Well, the more
167	 ;; pragmatic reason is to get unique faces for the test
168	 ;; suite.)
169	 'font-lock-doc-markup-face
170    c-label-face-name))
171
172(defconst c-negation-char-face-name
173  (if (c-face-name-p 'font-lock-negation-char-face)
174      ;; Emacs 22 has a special face for negation chars.
175      'font-lock-negation-char-face))
176
177(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
178
179(defun c-make-inverse-face (oldface newface)
180  ;; Emacs and XEmacs have completely different face manipulation
181  ;; routines. :P
182  (copy-face oldface newface)
183  (cond ((fboundp 'face-inverse-video-p)
184	 ;; Emacs.  This only looks at the inverse flag in the current
185	 ;; frame.  Other display configurations might be different,
186	 ;; but it can only show if the same Emacs has frames on
187	 ;; e.g. a color and a monochrome display simultaneously.
188	 (unless (face-inverse-video-p oldface)
189	   (invert-face newface)))
190	((fboundp 'face-property-instance)
191	 ;; XEmacs.  Same pitfall here.
192	 (unless (face-property-instance oldface 'reverse)
193	   (invert-face newface)))))
194
195(defvar c-annotation-face 'c-annotation-face)
196
197(defface c-annotation-face
198  '((default :inherit font-lock-constant-face))
199  "Face for highlighting annotations in Java mode and similar modes."
200  :version "24.1"
201  :group 'c)
202
203(eval-and-compile
204  ;; We need the following definitions during compilation since they're
205  ;; used when the `c-lang-defconst' initializers are evaluated.  Define
206  ;; them at runtime too for the sake of derived modes.
207
208  ;; This indicates the "font locking context", and is set just before
209  ;; fontification is done.  If non-nil, it says, e.g., point starts
210  ;; from within a #if preprocessor construct.
211  (defvar c-font-lock-context nil)
212  (make-variable-buffer-local 'c-font-lock-context)
213
214  (defmacro c-put-font-lock-face (from to face)
215    ;; Put a face on a region (overriding any existing face) in the way
216    ;; font-lock would do it.  In XEmacs that means putting an
217    ;; additional font-lock property, or else the font-lock package
218    ;; won't recognize it as fontified and might override it
219    ;; incorrectly.
220    ;;
221    ;; This function does a hidden buffer change.
222    (declare (debug t))
223    (if (fboundp 'font-lock-set-face)
224	;; Note: This function has no docstring in XEmacs so it might be
225	;; considered internal.
226	`(font-lock-set-face ,from ,to ,face)
227      `(put-text-property ,from ,to 'face ,face)))
228
229  (defmacro c-remove-font-lock-face (from to)
230    ;; This is the inverse of `c-put-font-lock-face'.
231    ;;
232    ;; This function does a hidden buffer change.
233    (declare (debug t))
234    (if (fboundp 'font-lock-remove-face)
235	`(font-lock-remove-face ,from ,to)
236      `(remove-text-properties ,from ,to '(face nil))))
237
238  (defmacro c-put-font-lock-string-face (from to)
239    ;; Put `font-lock-string-face' on a string.  The surrounding
240    ;; quotes are included in Emacs but not in XEmacs.  The passed
241    ;; region should include them.
242    ;;
243    ;; This function does a hidden buffer change.
244    (declare (debug t))
245    (if (featurep 'xemacs)
246	`(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
247      `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
248
249  (defmacro c-fontify-types-and-refs (varlist &rest body)
250    (declare (indent 1) (debug let*))
251    ;; Like `let', but additionally activates `c-record-type-identifiers'
252    ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
253    ;; accordingly on exit.
254    ;;
255    ;; This function does hidden buffer changes.
256    `(let ((c-record-type-identifiers t)
257	   c-record-ref-identifiers
258	   ,@varlist)
259       (prog1 (progn ,@body)
260	 (c-fontify-recorded-types-and-refs))))
261
262  (defun c-skip-comments-and-strings (limit)
263    ;; If the point is within a region fontified as a comment or
264    ;; string literal skip to the end of it or to LIMIT, whichever
265    ;; comes first, and return t.  Otherwise return nil.  The match
266    ;; data is not clobbered.
267    ;;
268    ;; This function might do hidden buffer changes.
269    (when (c-got-face-at (point) c-literal-faces)
270      (while (progn
271	       (goto-char (c-next-single-property-change
272			   (point) 'face nil limit))
273	       (and (< (point) limit)
274		    (c-got-face-at (point) c-literal-faces))))
275      t))
276
277  (defun c-make-syntactic-matcher (regexp)
278    ;; Returns a byte compiled function suitable for use in place of a
279    ;; regexp string in a `font-lock-keywords' matcher, except that
280    ;; only matches outside comments and string literals count.
281    ;;
282    ;; This function does not do any hidden buffer changes, but the
283    ;; generated functions will.  (They are however used in places
284    ;; covered by the font-lock context.)
285    (byte-compile
286     `(lambda (limit)
287	(let (res)
288	  (while (and (setq res (re-search-forward ,regexp limit t))
289		      (progn
290			(goto-char (match-beginning 0))
291			(or (c-skip-comments-and-strings limit)
292			    (progn
293			      (goto-char (match-end 0))
294			      nil)))))
295	  res))))
296
297  (defun c-make-font-lock-search-form (regexp highlights &optional check-point)
298    ;; Return a lisp form which will fontify every occurrence of REGEXP
299    ;; (a regular expression, NOT a function) between POINT and `limit'
300    ;; with HIGHLIGHTS, a list of highlighters as specified on page
301    ;; "Search-based Fontification" in the elisp manual.  If CHECK-POINT
302    ;; is non-nil, we will check (< (point) limit) in the main loop.
303    `(while
304	 ,(if check-point
305	      `(and (< (point) limit)
306		    (re-search-forward ,regexp limit t))
307	    `(re-search-forward ,regexp limit t))
308       (unless (progn
309		 (goto-char (match-beginning 0))
310		 (c-skip-comments-and-strings limit))
311	 (goto-char (match-end 0))
312	 ,@(mapcar
313	    (lambda (highlight)
314	      (if (integerp (car highlight))
315		  ;; e.g. highlight is (1 font-lock-type-face t)
316		  (progn
317		    (unless (eq (nth 2 highlight) t)
318		      (error
319		       "The override flag must currently be t in %s"
320		       highlight))
321		    (when (nth 3 highlight)
322		      (error
323		       "The laxmatch flag may currently not be set in %s"
324		       highlight))
325		    `(save-match-data
326		       (c-put-font-lock-face
327			(match-beginning ,(car highlight))
328			(match-end ,(car highlight))
329			,(elt highlight 1))))
330		;; highlight is an "ANCHORED HIGHLIGHTER" of the form
331		;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...)
332		(when (nth 3 highlight)
333		  (error "Match highlights currently not supported in %s"
334			 highlight))
335		`(progn
336		   ,(nth 1 highlight)
337		   (save-match-data ,(car highlight))
338		   ,(nth 2 highlight))))
339	    highlights))))
340
341  (defun c-make-font-lock-search-function (regexp &rest highlights)
342    ;; This function makes a byte compiled function that works much like
343    ;; a matcher element in `font-lock-keywords'.  It cuts out a little
344    ;; bit of the overhead compared to a real matcher.  The main reason
345    ;; is however to pass the real search limit to the anchored
346    ;; matcher(s), since most (if not all) font-lock implementations
347    ;; arbitrarily limit anchored matchers to the same line, and also
348    ;; to insulate against various other irritating differences between
349    ;; the different (X)Emacs font-lock packages.
350    ;;
351    ;; REGEXP is the matcher, which must be a regexp.  Only matches
352    ;; where the beginning is outside any comment or string literal are
353    ;; significant.
354    ;;
355    ;; HIGHLIGHTS is a list of highlight specs, just like in
356    ;; `font-lock-keywords', with these limitations: The face is always
357    ;; overridden (no big disadvantage, since hits in comments etc are
358    ;; filtered anyway), there is no "laxmatch", and an anchored matcher
359    ;; is always a form which must do all the fontification directly.
360    ;; `limit' is a variable bound to the real limit in the context of
361    ;; the anchored matcher forms.
362    ;;
363    ;; This function does not do any hidden buffer changes, but the
364    ;; generated functions will.  (They are however used in places
365    ;; covered by the font-lock context.)
366
367    ;; Note: Replace `byte-compile' with `eval' to debug the generated
368    ;; lambda more easily.
369    (byte-compile
370     `(lambda (limit)
371	(let ( ;; The font-lock package in Emacs is known to clobber
372	      ;; `parse-sexp-lookup-properties' (when it exists).
373	      (parse-sexp-lookup-properties
374	       (cc-eval-when-compile
375		 (boundp 'parse-sexp-lookup-properties))))
376	  ,(c-make-font-lock-search-form regexp highlights))
377	nil)))
378
379  (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights)
380    ;; This function makes a byte compiled function that first moves back
381    ;; to the beginning of the current declaration (if any), then searches
382    ;; forward for matcher elements (as in `font-lock-keywords') and
383    ;; fontifies them.
384    ;;
385    ;; The motivation for moving back to the declaration start is to
386    ;; establish a context for the current text when, e.g., a character
387    ;; is typed on a C++ inheritance continuation line, or a jit-lock
388    ;; chunk starts there.
389    ;;
390    ;; The new function works much like a matcher element in
391    ;; `font-lock-keywords'.  It cuts out a little bit of the overhead
392    ;; compared to a real matcher.  The main reason is however to pass the
393    ;; real search limit to the anchored matcher(s), since most (if not
394    ;; all) font-lock implementations arbitrarily limit anchored matchers
395    ;; to the same line, and also to insulate against various other
396    ;; irritating differences between the different (X)Emacs font-lock
397    ;; packages.
398    ;;
399    ;; REGEXP is the matcher, which must be a regexp.  Only matches
400    ;; where the beginning is outside any comment or string literal are
401    ;; significant.
402    ;;
403    ;; HIGHLIGHTS is a list of highlight specs, just like in
404    ;; `font-lock-keywords', with these limitations: The face is always
405    ;; overridden (no big disadvantage, since hits in comments etc are
406    ;; filtered anyway), there is no "laxmatch", and an anchored matcher
407    ;; is always a form which must do all the fontification directly.
408    ;; `limit' is a variable bound to the real limit in the context of
409    ;; the anchored matcher forms.
410    ;;
411    ;; This function does not do any hidden buffer changes, but the
412    ;; generated functions will.  (They are however used in places
413    ;; covered by the font-lock context.)
414
415    ;; Note: Replace `byte-compile' with `eval' to debug the generated
416    ;; lambda more easily.
417    (byte-compile
418     `(lambda (limit)
419	(let ( ;; The font-lock package in Emacs is known to clobber
420	      ;; `parse-sexp-lookup-properties' (when it exists).
421	      (parse-sexp-lookup-properties
422	       (cc-eval-when-compile
423		 (boundp 'parse-sexp-lookup-properties)))
424	      (BOD-limit
425	       (c-determine-limit 1000)))
426	  (goto-char
427	   (let ((here (point)))
428	     (if (eq (car (c-beginning-of-decl-1 BOD-limit)) 'same)
429		 (point)
430	       here)))
431	  ,(c-make-font-lock-search-form regexp highlights))
432	nil)))
433
434  (defun c-make-font-lock-context-search-function (normal &rest state-stanzas)
435    ;; This function makes a byte compiled function that works much like
436    ;; a matcher element in `font-lock-keywords', with the following
437    ;; enhancement: the generated function will test for particular "font
438    ;; lock contexts" at the start of the region, i.e. is this point in
439    ;; the middle of some particular construct?  if so the generated
440    ;; function will first fontify the tail of the construct, before
441    ;; going into the main loop and fontify full constructs up to limit.
442    ;;
443    ;; The generated function takes one parameter called `limit', and
444    ;; will fontify the region between POINT and LIMIT.
445    ;;
446    ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is
447    ;; used to fontify the "regular" bit of the region.
448    ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP
449    ;; HIGHLIGHTS), each element coding one possible font lock context.
450
451    ;; o - REGEXP is a font-lock regular expression (NOT a function),
452    ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined
453    ;;   on page "Search-based Fontification" in the elisp manual.  As
454    ;;   yet (2009-06), they must have OVERRIDE set, and may not have
455    ;;   LAXMATCH set.
456    ;;
457    ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is
458    ;;   not quoted.
459    ;; o - LIM is a lisp form whose evaluation will yield the limit
460    ;;   position in the buffer for fontification by this stanza.
461    ;;
462    ;; This function does not do any hidden buffer changes, but the
463    ;; generated functions will.  (They are however used in places
464    ;; covered by the font-lock context.)
465    ;;
466    ;; Note: Replace `byte-compile' with `eval' to debug the generated
467    ;; lambda more easily.
468    (byte-compile
469     `(lambda (limit)
470	(let ( ;; The font-lock package in Emacs is known to clobber
471	      ;; `parse-sexp-lookup-properties' (when it exists).
472	      (parse-sexp-lookup-properties
473	       (cc-eval-when-compile
474		 (boundp 'parse-sexp-lookup-properties))))
475	  ,@(mapcar
476	     (lambda (stanza)
477	       (let ((state (car stanza))
478		     (lim (nth 1 stanza))
479		     (regexp (nth 2 stanza))
480		     (highlights (cdr (cddr stanza))))
481		 `(if (eq c-font-lock-context ',state)
482		      (let ((limit ,lim))
483			,(c-make-font-lock-search-form
484			  regexp highlights)))))
485	     state-stanzas)
486	  ;; In the next form, check that point hasn't been moved beyond
487	  ;; `limit' in any of the above stanzas.
488	  ,(c-make-font-lock-search-form (car normal) (cdr normal) t)
489	  nil)))))
490
491(defun c-fontify-recorded-types-and-refs ()
492  ;; Convert the ranges recorded on `c-record-type-identifiers' and
493  ;; `c-record-ref-identifiers' to fontification.
494  ;;
495  ;; This function does hidden buffer changes.
496  (let (elem)
497    (while (consp c-record-type-identifiers)
498      (setq elem (car c-record-type-identifiers)
499	    c-record-type-identifiers (cdr c-record-type-identifiers))
500      (c-put-font-lock-face (car elem) (cdr elem)
501			    'font-lock-type-face))
502    (while c-record-ref-identifiers
503      (setq elem (car c-record-ref-identifiers)
504	    c-record-ref-identifiers (cdr c-record-ref-identifiers))
505      ;; Note that the reference face is a variable that is
506      ;; dereferenced, since it's an alias in Emacs.
507      (c-put-font-lock-face (car elem) (cdr elem)
508			    c-reference-face-name))))
509
510(c-lang-defconst c-cpp-matchers
511  "Font lock matchers for preprocessor directives and purely lexical
512stuff.  Used on level 1 and higher."
513
514  ;; Note: `c-font-lock-declarations' assumes that no matcher here
515  ;; sets `font-lock-type-face' in languages where
516  ;; `c-recognize-<>-arglists' is set.
517
518  t `(,@(when (c-lang-const c-opt-cpp-prefix)
519	  (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
520		 (ncle-depth (regexp-opt-depth noncontinued-line-end))
521		 (sws-depth (c-lang-const c-syntactic-ws-depth))
522		 (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
523
524	    `(;; Fontify "invalid" comment delimiters
525	      ,@(when (and (c-lang-const c-block-comment-starter)
526			   (c-lang-const c-line-comment-starter))
527		  `(c-maybe-font-lock-wrong-style-comments))
528
529	      ;; The stuff after #error and #warning is a message, so
530	      ;; fontify it as a string.
531	      ,@(when (c-lang-const c-cpp-message-directives)
532		  (let* ((re (c-make-keywords-re 'appendable ; nil
533			       (c-lang-const c-cpp-message-directives)))
534			 (re-depth (regexp-opt-depth re)))
535		    `((,(concat noncontinued-line-end
536				(c-lang-const c-opt-cpp-prefix)
537				re
538				"\\s +\\(.*\\)$")
539		       ,(+ ncle-depth re-depth 1) font-lock-string-face t))))
540
541	      ;; Fontify filenames in #include <...> as strings.
542	      ,@(when (c-lang-const c-cpp-include-directives)
543		  (let* ((re (c-make-keywords-re nil
544			       (c-lang-const c-cpp-include-directives)))
545			 (re-depth (regexp-opt-depth re)))
546		    ;; We used to use a font-lock "anchored matcher" here for
547		    ;; the paren syntax.  This failed when the ">" was at EOL,
548		    ;; since `font-lock-fontify-anchored-keywords' terminated
549		    ;; its loop at EOL without executing our lambda form at
550		    ;; all.
551		    `((,(c-make-font-lock-search-function
552			 (concat noncontinued-line-end
553				 (c-lang-const c-opt-cpp-prefix)
554				 re
555				 (c-lang-const c-syntactic-ws)
556				 "\\(<[^>\n\r]*>?\\)")
557			 `(,(+ ncle-depth re-depth sws-depth 1)
558			   font-lock-string-face t)
559			 `((let ((beg (match-beginning
560				       ,(+ ncle-depth re-depth sws-depth 1)))
561				 (end (1- (match-end ,(+ ncle-depth re-depth
562							 sws-depth 1)))))
563			     (if (eq (char-after end) ?>)
564				 (progn
565				   (c-mark-<-as-paren beg)
566				   (c-mark->-as-paren end))
567			       (c-unmark-<->-as-paren beg)))
568			   nil))))))
569
570	      ;; #define.
571	      ,@(when (c-lang-const c-opt-cpp-macro-define)
572		  `((,(c-make-font-lock-search-function
573		       (concat
574			noncontinued-line-end
575			(c-lang-const c-opt-cpp-prefix)
576			(c-lang-const c-opt-cpp-macro-define)
577			(c-lang-const c-nonempty-syntactic-ws)
578			"\\(" (c-lang-const ; 1 + ncle + nsws
579			       c-symbol-key) "\\)"
580			(concat "\\("	; 2 + ncle + nsws + c-sym-key
581				;; Macro with arguments - a "function".
582				"\\((\\)" ; 3 + ncle + nsws + c-sym-key
583				"\\|"
584				;; Macro without arguments - a "variable".
585				"\\([^(]\\|$\\)"
586				"\\)"))
587		       `((if (match-beginning
588			      ,(+ 3 ncle-depth nsws-depth
589				  (c-lang-const c-symbol-key-depth)))
590
591			     ;; "Function".  Fontify the name and the arguments.
592			     (save-restriction
593			       (c-put-font-lock-face
594				(match-beginning ,(+ 1 ncle-depth nsws-depth))
595				(match-end ,(+ 1 ncle-depth nsws-depth))
596				'font-lock-function-name-face)
597			       (goto-char
598				(match-end
599				 ,(+ 3 ncle-depth nsws-depth
600				     (c-lang-const c-symbol-key-depth))))
601
602			       (narrow-to-region (point-min) limit)
603			       (while (and
604				       (progn
605					 (c-forward-syntactic-ws)
606					 (looking-at c-symbol-key))
607				       (progn
608					 (c-put-font-lock-face
609					  (match-beginning 0) (match-end 0)
610					  'font-lock-variable-name-face)
611					 (goto-char (match-end 0))
612					 (c-forward-syntactic-ws)
613					 (eq (char-after) ?,)))
614				 (forward-char)))
615
616			   ;; "Variable".
617			   (c-put-font-lock-face
618			    (match-beginning ,(+ 1 ncle-depth nsws-depth))
619			    (match-end ,(+ 1 ncle-depth nsws-depth))
620			    'font-lock-variable-name-face)))))))
621
622	      ;; Fontify cpp function names in preprocessor
623	      ;; expressions in #if and #elif.
624	      ,@(when (and (c-lang-const c-cpp-expr-directives)
625			   (c-lang-const c-cpp-expr-functions))
626		  (let ((ced-re (c-make-keywords-re t
627				  (c-lang-const c-cpp-expr-directives)))
628			(cef-re (c-make-keywords-re t
629				  (c-lang-const c-cpp-expr-functions))))
630
631		    `((,(c-make-font-lock-context-search-function
632			 `(,(concat noncontinued-line-end
633				    (c-lang-const c-opt-cpp-prefix)
634				    ced-re ; 1 + ncle-depth
635				    ;; Match the whole logical line to look
636				    ;; for the functions in.
637				    "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")
638			   ((let ((limit (match-end 0)))
639			      (while (re-search-forward ,cef-re limit 'move)
640				(c-put-font-lock-face (match-beginning 1)
641						      (match-end 1)
642						      c-preprocessor-face-name)))
643			    (goto-char (match-end ,(1+ ncle-depth)))))
644			 `(in-cpp-expr
645			   (save-excursion (c-end-of-macro) (point))
646			   ,cef-re
647			   (1 c-preprocessor-face-name t)))))))
648
649	      ;; Fontify the directive names.
650	      (,(c-make-font-lock-search-function
651		 (concat noncontinued-line-end
652			 "\\("
653			 (c-lang-const c-opt-cpp-prefix)
654			 "[" (c-lang-const c-symbol-chars) "]+"
655			 "\\)")
656		 `(,(1+ ncle-depth) c-preprocessor-face-name t)))
657
658	      (eval . (list ,(c-make-syntactic-matcher
659			      (concat noncontinued-line-end
660				      (c-lang-const c-opt-cpp-prefix)
661				      "if\\(n\\)def\\>"))
662			    ,(+ ncle-depth 1)
663			    c-negation-char-face-name
664			    'append))
665	      )))
666
667      ,@(when (c-major-mode-is 'pike-mode)
668	  ;; Recognize hashbangs in Pike.
669	  '((eval . (list "\\`#![^\n\r]*"
670			  0 c-preprocessor-face-name))))
671
672      ;; Make hard spaces visible through an inverted `font-lock-warning-face'.
673      (eval . (list
674	       "\240"
675	       0 (progn
676		   (unless (c-face-name-p 'c-nonbreakable-space-face)
677		     (c-make-inverse-face 'font-lock-warning-face
678					  'c-nonbreakable-space-face))
679		   ''c-nonbreakable-space-face)))
680      ))
681
682(defun c-font-lock-invalid-single-quotes (limit)
683  ;; This function will be called from font-lock for a region bounded by POINT
684  ;; and LIMIT, as though it were to identify a keyword for
685  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
686  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
687  ;; Fontification".
688  ;;
689  ;; This function fontifies invalid single quotes with
690  ;; `font-lock-warning-face'.  These are the single quotes which
691  ;; o - aren't inside a literal;
692  ;; o - are marked with a syntax-table text property value '(1); and
693  ;; o - are NOT marked with a non-null c-digit-separator property.
694  (let ((limits (c-literal-limits))
695	state beg end)
696    (if limits
697	(goto-char (cdr limits)))	; Even for being in a ' '
698    (while (< (point) limit)
699      (setq beg (point))
700      (setq state (parse-partial-sexp (point) limit nil nil nil 'syntax-table))
701      (setq end (point))
702      (goto-char beg)
703      (while (progn (skip-chars-forward "^'" end)
704		    (< (point) end))
705	(if (and (equal (c-get-char-property (point) 'syntax-table) '(1))
706		 (not (c-get-char-property (point) 'c-digit-separator)))
707	    (c-put-font-lock-face (point) (1+ (point)) font-lock-warning-face))
708	(forward-char))
709      (parse-partial-sexp end limit nil nil state 'syntax-table)))
710    nil)
711
712(defun c-maybe-font-lock-wrong-style-comments (limit)
713  ;; This function will be called from font-lock-for a region bounded by POINT
714  ;; and LIMIT, as though it were to identify a keyword for
715  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
716  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
717  ;; Fontification".
718  ;;
719  ;; This function fontifies "invalid" comment delimiters with
720  ;; `font-lock-warning-face'.  A delimiter is "invalid" when
721  ;; `c-mark-wrong-style-of-comment' is non-nil, and the delimiter style is
722  ;; not the default specified by `c-block-comment-flag'.
723  (when c-mark-wrong-style-of-comment
724    (let* ((lit (c-semi-pp-to-literal (point)))
725	   (s (car lit))		; parse-partial-sexp state.
726	   )
727      ;; First, deal with and move out of any literal we start in.
728      (cond
729       ((null (cadr lit)))		; Not in a literal
730       ((eq (cadr lit) 'string)
731	(setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)))
732       ((and (not c-block-comment-flag) ; In an "invalid" block comment
733	     (eq (cadr lit) 'c))
734	(setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
735	;; Font lock the block comment ender with warning face.
736	(when (not (nth 4 s))
737	  (c-put-font-lock-face (- (point) (length c-block-comment-ender))
738				(point) font-lock-warning-face)))
739       (t ; In a line comment, or a "valid" block comment
740	(setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))))
741
742      (while (< (point) limit)
743	(setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
744	(cond
745	 ((or (nth 3 s)			; In a string
746	      (and (nth 4 s)		; In a comment
747		   (eq (nth 7 s)	; Comment style
748		       (if c-block-comment-flag
749			   nil		; Block comment
750			 1))))	; Line comment
751	    ;; Move over a "valid" literal.
752	  (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)))
753	 ((nth 4 s)			; In an invalid comment
754	 ;; Fontify the invalid comment opener.
755	  (c-put-font-lock-face (nth 8 s) (point) font-lock-warning-face)
756	  ;; Move to end of comment or LIMIT.
757	  (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
758	  ;; Fontify an invalid block comment ender, if that's what we have.
759	  (when (and (not c-block-comment-flag)
760		     (not (nth 4 s)))	; We're outside the comment
761	    (c-put-font-lock-face (- (point) (length c-block-comment-ender))
762				  (point) font-lock-warning-face)))))))
763  nil)
764
765(c-lang-defconst c-basic-matchers-before
766  "Font lock matchers for basic keywords, labels, references and various
767other easily recognizable things that should be fontified before generic
768casts and declarations are fontified.  Used on level 2 and higher."
769
770  ;; Note: `c-font-lock-declarations' assumes that no matcher here
771  ;; sets `font-lock-type-face' in languages where
772  ;; `c-recognize-<>-arglists' is set.
773
774  t `(;; Put a warning face on the opener of unclosed strings that
775      ;; can't span lines and on the "terminating" newlines.  Later font
776      ;; lock packages have a `font-lock-syntactic-face-function' for
777      ;; this, but it doesn't give the control we want since any
778      ;; fontification done inside the function will be
779      ;; unconditionally overridden.
780      ("\\s|" 0 font-lock-warning-face t nil)
781
782      ;; Invalid single quotes.
783      c-font-lock-invalid-single-quotes
784
785      ;; Fontify multiline strings.
786      ,@(when (c-lang-const c-ml-string-opener-re)
787	  '(c-font-lock-ml-strings))
788
789      ;; Fontify keyword constants.
790      ,@(when (c-lang-const c-constant-kwds)
791	  (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
792	    (if (c-major-mode-is 'pike-mode)
793		;; No symbol is a keyword after "->" in Pike.
794		`((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
795					 "\\<\\(" re "\\)\\>")
796				2 c-constant-face-name)))
797	      `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
798			      1 c-constant-face-name))))))
799
800      ;; Fontify all keywords except the primitive types.
801      ,(if (c-major-mode-is 'pike-mode)
802	   ;; No symbol is a keyword after "->" in Pike.
803	   `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
804		      "\\<" (c-lang-const c-regular-keywords-regexp))
805	     2 font-lock-keyword-face)
806	 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
807	   1 font-lock-keyword-face))
808
809      ;; Fontify leading identifiers in fully qualified names like
810      ;; "foo::bar" in languages that supports such things.
811      ,@(when (c-lang-const c-opt-identifier-concat-key)
812	  (if (c-major-mode-is 'java-mode)
813	      ;; Java needs special treatment since "." is used both to
814	      ;; qualify names and in normal indexing.  Here we look for
815	      ;; capital characters at the beginning of an identifier to
816	      ;; recognize the class.  "*" is also recognized to cover
817	      ;; wildcard import declarations.  All preceding dot separated
818	      ;; identifiers are taken as package names and therefore
819	      ;; fontified as references.
820	      `(,(c-make-font-lock-search-function
821		  ;; Search for class identifiers preceded by ".".  The
822		  ;; anchored matcher takes it from there.
823		  (concat (c-lang-const c-opt-identifier-concat-key)
824			  (c-lang-const c-simple-ws) "*"
825			  (concat "\\("
826				  "[" c-upper "]"
827				  "[" (c-lang-const c-symbol-chars) "]*"
828				  "\\|"
829				  "\\*"
830				  "\\)"))
831		  `((let (id-end)
832		      (goto-char (1+ (match-beginning 0)))
833		      (while (and (eq (char-before) ?.)
834				  (progn
835				    (backward-char)
836				    (c-backward-syntactic-ws)
837				    (setq id-end (point))
838				    (< (skip-chars-backward
839					,(c-lang-const c-symbol-chars))
840				       0))
841				  (not (get-text-property (point) 'face)))
842			(c-put-font-lock-face (point) id-end
843					      c-reference-face-name)
844			(c-backward-syntactic-ws)))
845		    nil
846		    (goto-char (match-end 0)))))
847
848	    `((,(byte-compile
849		 ;; Must use a function here since we match longer than
850		 ;; we want to move before doing a new search.  This is
851		 ;; not necessary for XEmacs since it restarts the
852		 ;; search from the end of the first highlighted
853		 ;; submatch (something that causes problems in other
854		 ;; places).
855		 `(lambda (limit)
856		    (while (re-search-forward
857			    ,(concat "\\(\\<" ; 1
858				     "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
859				     (c-lang-const c-simple-ws) "*"
860				     (c-lang-const c-opt-identifier-concat-key)
861				     (c-lang-const c-simple-ws) "*"
862				     "\\)"
863				     "\\("
864				     (c-lang-const c-opt-after-id-concat-key)
865				     "\\)")
866			    limit t)
867		      (unless (progn
868				(goto-char (match-beginning 0))
869				(c-skip-comments-and-strings limit))
870			(or (get-text-property (match-beginning 2) 'face)
871			    (c-put-font-lock-face (match-beginning 2)
872						  (match-end 2)
873						  c-reference-face-name))
874			(goto-char (match-end 1))))))))))
875
876      ;; Fontify the special declarations in Objective-C.
877      ,@(when (c-major-mode-is 'objc-mode)
878	  `(;; Fontify class names in the beginning of message expressions.
879	    ,(c-make-font-lock-search-function
880	      "\\["
881	      '((c-fontify-types-and-refs ()
882		  (c-forward-syntactic-ws limit)
883		  (let ((start (point)))
884		    ;; In this case we accept both primitive and known types.
885		    (when (eq (c-forward-type) 'known)
886		      (goto-char start)
887		      (let ((c-promote-possible-types t))
888			(c-forward-type))))
889		  (if (> (point) limit) (goto-char limit)))))
890
891	    ;; The @interface/@implementation/@protocol directives.
892	    ,(c-make-font-lock-search-function
893	      (concat "\\<"
894		      (regexp-opt
895		       '("@interface" "@implementation" "@protocol")
896		       t)
897		      "\\>")
898	      '((c-fontify-types-and-refs
899		    (;; The font-lock package in Emacs is known to clobber
900		     ;; `parse-sexp-lookup-properties' (when it exists).
901		     (parse-sexp-lookup-properties
902		      (cc-eval-when-compile
903			(boundp 'parse-sexp-lookup-properties))))
904		  (c-forward-objc-directive)
905		  nil)
906		(goto-char (match-beginning 0))))))
907
908      (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name))
909      ))
910
911(defun c-font-lock-complex-decl-prepare (limit)
912  ;; This function will be called from font-lock for a region bounded by POINT
913  ;; and LIMIT, as though it were to identify a keyword for
914  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
915  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
916  ;; Fontification".
917  ;;
918  ;; Called before any of the matchers in `c-complex-decl-matchers'.
919  ;;
920  ;; This function does hidden buffer changes.
921
922  ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
923  (c-skip-comments-and-strings limit)
924  (when (< (point) limit)
925
926    ;; Clear the c-type char properties which mark the region, to recalculate
927    ;; them properly.  The most interesting properties are those put on the
928    ;; closest token before the region.
929    (save-excursion
930      (let ((pos (point)))
931	(c-backward-syntactic-ws (max (- (point) 500) (point-min)))
932	(c-clear-char-properties
933	 (if (and (not (bobp))
934		  (memq (c-get-char-property (1- (point)) 'c-type)
935			'(c-decl-arg-start
936			  c-decl-end
937			  c-decl-id-start
938			  c-decl-type-start)))
939	     (1- (point))
940	   pos)
941	 limit 'c-type)))
942
943    ;; Update `c-state-cache' to the beginning of the region.  This will
944    ;; make `c-beginning-of-syntax' go faster when it's used later on,
945    ;; and it's near the point most of the time.
946    (c-parse-state)
947
948    ;; Check if the fontified region starts inside a declarator list so
949    ;; that `c-font-lock-declarators' should be called at the start.
950    ;; The declared identifiers are font-locked correctly as types, if
951    ;; that is what they are.
952    (let ((prop (save-excursion
953		  (c-backward-syntactic-ws (max (- (point) 500) (point-min)))
954		  (unless (bobp)
955		    (c-get-char-property (1- (point)) 'c-type)))))
956      (when (memq prop '(c-decl-id-start c-decl-type-start))
957	(c-forward-syntactic-ws limit)
958	(c-font-lock-declarators limit t (eq prop 'c-decl-type-start)
959				 (not (c-bs-at-toplevel-p (point))))))
960
961    (setq c-font-lock-context ;; (c-guess-font-lock-context)
962	  (save-excursion
963	    (if (and c-cpp-expr-intro-re
964		     (c-beginning-of-macro)
965		     (looking-at c-cpp-expr-intro-re))
966		'in-cpp-expr)))
967    nil))
968
969(defun c-font-lock-<>-arglists (limit)
970  ;; This function will be called from font-lock for a region bounded by POINT
971  ;; and LIMIT, as though it were to identify a keyword for
972  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
973  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
974  ;; Fontification".
975  ;;
976  ;; Fontify types and references in names containing angle bracket
977  ;; arglists from the point to LIMIT.  Note that
978  ;; `c-font-lock-declarations' has already handled many of them.
979  ;;
980  ;; This function might do hidden buffer changes.
981
982  (c-skip-comments-and-strings limit)
983  (when (< (point) limit)
984
985    (let (;; The font-lock package in Emacs is known to clobber
986	  ;; `parse-sexp-lookup-properties' (when it exists).
987	  (parse-sexp-lookup-properties
988	   (cc-eval-when-compile
989	     (boundp 'parse-sexp-lookup-properties)))
990	  (c-parse-and-markup-<>-arglists t)
991	  c-restricted-<>-arglists
992	  id-start id-end id-face pos kwd-sym
993	  old-pos)
994
995      (while (and (< (point) limit)
996		  (setq old-pos (point))
997		  (c-syntactic-re-search-forward "<" limit t nil t))
998	(setq pos (point))
999	(save-excursion
1000	  (backward-char)
1001	  (c-backward-syntactic-ws old-pos)
1002	  (if (re-search-backward
1003	       (concat "\\(\\`\\|" c-nonsymbol-key "\\)\\(" c-symbol-key"\\)\\=")
1004	       old-pos t)
1005	      (setq id-start (match-beginning 2)
1006		    id-end (match-end 2))
1007	    (setq id-start nil id-end nil)))
1008
1009	(when id-start
1010	  (goto-char id-start)
1011	  (unless (c-skip-comments-and-strings limit)
1012	    (setq kwd-sym nil
1013		  c-restricted-<>-arglists nil
1014		  id-face (get-text-property id-start 'face))
1015
1016	    (if (cond
1017		 ((eq id-face 'font-lock-type-face)
1018		  ;; The identifier got the type face so it has already been
1019		  ;; handled in `c-font-lock-declarations'.
1020		  nil)
1021
1022		 ((eq id-face 'font-lock-keyword-face)
1023		  (when (looking-at c-opt-<>-sexp-key)
1024		    ;; There's a special keyword before the "<" that tells
1025		    ;; that it's an angle bracket arglist.
1026		    (setq kwd-sym (c-keyword-sym (match-string 2)))))
1027
1028		 (t
1029		  ;; There's a normal identifier before the "<".  If we're not in
1030		  ;; a declaration context then we set `c-restricted-<>-arglists'
1031		  ;; to avoid recognizing templates in function calls like "foo (a
1032		  ;; < b, c > d)".
1033		  (c-backward-syntactic-ws)
1034		  (when (and (memq (char-before) '(?\( ?,))
1035			     (not (eq (get-text-property (1- (point)) 'c-type)
1036				      'c-decl-arg-start)))
1037		    (setq c-restricted-<>-arglists t))
1038		  t))
1039
1040		(progn
1041		  (goto-char (1- pos))
1042		  ;; Check for comment/string both at the identifier and
1043		  ;; at the "<".
1044		  (unless (c-skip-comments-and-strings limit)
1045
1046		    (c-fontify-types-and-refs ()
1047		      (when (c-forward-<>-arglist (c-keyword-member
1048						   kwd-sym 'c-<>-type-kwds))
1049			(when (and c-opt-identifier-concat-key
1050				   (not (get-text-property id-start 'face)))
1051			  (c-forward-syntactic-ws)
1052			  (cond ((looking-at c-opt-identifier-concat-key)
1053				 (c-put-font-lock-face id-start id-end
1054						       c-reference-face-name))
1055				((eq (char-after) ?\())
1056				(t (c-put-font-lock-face id-start id-end
1057							 'font-lock-type-face))))))
1058
1059		    (goto-char pos)))
1060	      (goto-char pos)))))))
1061  nil)
1062
1063(defun c-font-lock-declarators (limit list types not-top
1064				      &optional template-class)
1065  ;; Assuming the point is at the start of a declarator in a declaration,
1066  ;; fontify the identifier it declares.  (If TYPES is t, it does this via the
1067  ;; macro `c-fontify-types-and-refs'.)
1068  ;;
1069  ;; If LIST is non-nil, also fontify the ids in any following declarators in
1070  ;; a comma separated list (e.g.  "foo" and "*bar" in "int foo = 17, *bar;");
1071  ;; additionally, mark the commas with c-type property 'c-decl-id-start or
1072  ;; 'c-decl-type-start (according to TYPES).  Stop at LIMIT.
1073  ;;
1074  ;; If TYPES is t, fontify all identifiers as types, if it is nil fontify as
1075  ;; either variables or functions, otherwise TYPES is a face to use.  If
1076  ;; NOT-TOP is non-nil, we are not at the top-level ("top-level" includes
1077  ;; being directly inside a class or namespace, etc.).
1078  ;;
1079  ;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters
1080  ;; and was introduced by, e.g. "typename" or "class", such that if there is
1081  ;; a default (introduced by "="), it will be fontified as a type.
1082  ;; E.g. "<class X = Y>".
1083  ;;
1084  ;; Nil is always returned.  The function leaves point at the delimiter after
1085  ;; the last declarator it processes.
1086  ;;
1087  ;; This function might do hidden buffer changes.
1088
1089  ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
1090  (c-fontify-types-and-refs
1091      ()
1092    (c-do-declarators
1093     limit list not-top
1094     (cond ((eq types t) 'c-decl-type-start)
1095	   ((null types) 'c-decl-id-start))
1096     (lambda (id-start _id-end end-pos _not-top is-function init-char)
1097       (if (eq types t)
1098	   ;; Register and fontify the identifier as a type.
1099	   (let ((c-promote-possible-types t))
1100	     (goto-char id-start)
1101	     (c-forward-type))
1102	 ;; The following doesn't work properly (yet, 2018-09-22).
1103	 ;; (c-put-font-lock-face id-start id-end
1104	 ;; 		       (if is-function
1105	 ;; 			   'font-lock-function-name-face
1106	 ;; 			 'font-lock-variable-name-face))
1107	 (when (and c-last-identifier-range
1108	 	    (not (get-text-property (car c-last-identifier-range)
1109	 				    'face)))
1110	   ;; We use `c-last-identifier-range' rather than `id-start' and
1111	   ;; `id-end', since the latter two can be erroneous.  E.g. in
1112	   ;; "~Foo", `id-start' is at the tilde.  This is a bug in
1113	   ;; `c-forward-declarator'.
1114	   (c-put-font-lock-face (car c-last-identifier-range)
1115	 			 (cdr c-last-identifier-range)
1116				 (cond
1117				  ((not (memq types '(nil t))) types)
1118				  (is-function 'font-lock-function-name-face)
1119				  (t 'font-lock-variable-name-face)))))
1120       (and template-class
1121	    (eq init-char ?=)		; C++ "<class X = Y>"?
1122	    (progn
1123	      (goto-char end-pos)
1124	      (c-forward-token-2 1 nil limit) ; Over "="
1125	      (let ((c-promote-possible-types t))
1126		(c-forward-type t))))))
1127    nil))
1128
1129(defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
1130  ;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS.
1131  ;; NOT-FRONT-DECL is non-nil when a declaration later in the buffer than
1132  ;; MATCH-POS has already been parsed.  TOPLEV is non-nil when MATCH-POS is
1133  ;; known to be at "top level", i.e. outside any braces, or directly inside a
1134  ;; namespace, class, etc.
1135  ;;
1136  ;; CONTEXT is the fontification context of MATCH-POS, and is one of the
1137  ;; following:
1138  ;; 'decl     In a comma-separated declaration context (typically
1139  ;;           inside a function declaration arglist).
1140  ;; '<>       In an angle bracket arglist.
1141  ;; 'arglist  Some other type of arglist.
1142  ;; 'top      Some other context and point is at the top-level (either
1143  ;;           outside any braces or directly inside a class or namespace,
1144  ;;           etc.)
1145  ;; nil       Some other context or unknown context.  Includes
1146  ;;           within the parens of an if, for, ... construct.
1147  ;; 'not-decl Definitely not in a declaration.
1148  ;;
1149  ;; RESTRICTED-<>-ARGLISTS is non-nil when a scan of template/generic
1150  ;; arguments lists (i.e. lists enclosed by <...>) is more strict about what
1151  ;; characters it allows within the list.
1152  (let ((type (and (> match-pos (point-min))
1153		   (c-get-char-property (1- match-pos) 'c-type))))
1154    (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
1155	   (cons (and toplev 'top) nil))
1156	  ;; A control flow expression or a decltype
1157	  ((and (eq (char-before match-pos) ?\()
1158		(save-excursion
1159		  (goto-char match-pos)
1160		  (backward-char)
1161		  (c-backward-token-2)
1162		  (cond
1163		   ((looking-at c-paren-stmt-key)
1164		    ;; Allow comma separated <> arglists in for statements.
1165		    (cons nil nil))
1166		   ((or (looking-at c-block-stmt-2-key)
1167			(looking-at c-block-stmt-1-2-key)
1168			(looking-at c-typeof-key))
1169		    (cons nil t))
1170		   (t nil)))))
1171	  ;; Near BOB.
1172	  ((<= match-pos (point-min))
1173	   (cons 'arglist t))
1174	  ;; Got a cached hit in a declaration arglist.
1175	  ((eq type 'c-decl-arg-start)
1176	   (cons 'decl nil))
1177	  ;; We're inside (probably) a brace list.
1178	  ((eq type 'c-not-decl)
1179	   (cons 'not-decl nil))
1180	  ;; Inside a C++11 lambda function arglist.
1181	  ((and (c-major-mode-is 'c++-mode)
1182		(eq (char-before match-pos) ?\()
1183		(save-excursion
1184		  (goto-char match-pos)
1185		  (c-backward-token-2)
1186		  (and
1187		   (c-safe (goto-char (scan-sexps (point) -1)))
1188		   (c-looking-at-c++-lambda-capture-list))))
1189	   (c-put-char-property (1- match-pos) 'c-type
1190				'c-decl-arg-start)
1191	   (cons 'decl nil))
1192	  ;; We're inside a brace list.
1193	  ((and (eq (char-before match-pos) ?{)
1194		(c-inside-bracelist-p (1- match-pos)
1195				      (cdr (c-parse-state))
1196				      nil))
1197	   (c-put-char-property (1- match-pos) 'c-type
1198				'c-not-decl)
1199	   (cons 'not-decl nil))
1200	  ;; We're inside an "ordinary" open brace.
1201	  ((eq (char-before match-pos) ?{)
1202	   (cons (and toplev 'top) nil))
1203	  ;; Inside an angle bracket arglist.
1204	  ((or (eq type 'c-<>-arg-sep)
1205	       (eq (char-before match-pos) ?<))
1206	   (cons '<> nil))
1207	  ;; Got a cached hit in some other type of arglist.
1208	  (type
1209	   (cons 'arglist t))
1210	  ;; We're at a C++ uniform initialization.
1211	  ((and (c-major-mode-is 'c++-mode)
1212		(eq (char-before match-pos) ?\()
1213		(save-excursion
1214		  (goto-char match-pos)
1215		  (and
1216		   (zerop (c-backward-token-2 2))
1217		   (looking-at c-identifier-start)
1218		   (c-got-face-at (point)
1219				  '(font-lock-variable-name-face)))))
1220	   (cons 'not-decl nil))
1221	  ((and not-front-decl
1222	   ;; The point is within the range of a previously
1223	   ;; encountered type decl expression, so the arglist
1224	   ;; is probably one that contains declarations.
1225	   ;; However, if `c-recognize-paren-inits' is set it
1226	   ;; might also be an initializer arglist.
1227		(or (not c-recognize-paren-inits)
1228		    (save-excursion
1229		      (goto-char match-pos)
1230		      (not (c-back-over-member-initializers)))))
1231	   ;; The result of this check is cached with a char
1232	   ;; property on the match token, so that we can look
1233	   ;; it up again when refontifying single lines in a
1234	   ;; multiline declaration.
1235	   (c-put-char-property (1- match-pos)
1236				'c-type 'c-decl-arg-start)
1237	   (cons 'decl nil))
1238	  ;; Got (an) open paren(s) preceded by an arith operator.
1239	  ((and (eq (char-before match-pos) ?\()
1240		(save-excursion
1241		  (goto-char match-pos)
1242		  (while
1243		      (and (zerop (c-backward-token-2))
1244			   (eq (char-after) ?\()))
1245		  (looking-at c-arithmetic-op-regexp)))
1246	   (cons nil nil))
1247	  ;; In a C++ member initialization list.
1248	  ((and (eq (char-before match-pos) ?,)
1249	  	(c-major-mode-is 'c++-mode)
1250	  	(save-excursion
1251		  (goto-char match-pos)
1252		  (c-back-over-member-initializers)))
1253	   (c-put-char-property (1- match-pos) 'c-type 'c-not-decl)
1254	   (cons 'not-decl nil))
1255	  ;; At start of a declaration inside a declaration paren.
1256	  ((save-excursion
1257	     (goto-char match-pos)
1258	     (and (memq (char-before match-pos) '(?\( ?\,))
1259		  (c-go-up-list-backward match-pos
1260					  ; c-determine-limit is too slow, here.
1261					 (max (- (point) 2000) (point-min)))
1262		  (eq (char-after) ?\()
1263		  (let ((type (c-get-char-property (point) 'c-type)))
1264		    (or (memq type '(c-decl-arg-start c-decl-type-start))
1265			(and
1266			 (progn (c-backward-syntactic-ws) t)
1267			 (c-back-over-compound-identifier)
1268			 (progn
1269			   (c-backward-syntactic-ws)
1270			   (or (bobp)
1271			       (progn
1272				 (setq type (c-get-char-property (1- (point))
1273								 'c-type))
1274				 (memq type '(c-decl-arg-start
1275					      c-decl-type-start))))))))))
1276	   (cons 'decl nil))
1277	  (t (cons 'arglist t)))))
1278
1279(defun c-font-lock-single-decl (limit decl-or-cast match-pos context toplev)
1280  ;; Try to fontify a single declaration, together with all its declarators.
1281  ;; Return nil if we're successful, non-nil if we fail.  POINT should be
1282  ;; positioned at the start of the putative declaration before calling.
1283  ;; POINT is left undefined by this function.
1284  ;;
1285  ;; LIMIT sets a maximum position we'll fontify out to.
1286  ;; DECL-OR-CAST has the form of a result from `c-forward-decl-or-cast-1',
1287  ;;   and must indicate a declaration (i.e. not be nil or 'cast).
1288  ;; MATCH-POS is the position after the last symbol before the decl.
1289  ;; CONTEXT is the context of the current decl., as determined by
1290  ;;   c-get-fontification-context.
1291  ;; TOPLEV is non-nil if the decl. is at the top level (i.e. outside any
1292  ;;   braces, or directly inside a class, namespace, etc.)
1293
1294  ;; Do we have an expression as the second or third clause of
1295  ;; a "for" paren expression?
1296  (if (save-excursion
1297	(and
1298	 (car (cddr decl-or-cast))	; maybe-expression flag.
1299	 (c-go-up-list-backward nil (c-determine-limit 500))
1300	 (eq (char-after) ?\()
1301	 (progn (c-backward-syntactic-ws)
1302		(c-simple-skip-symbol-backward))
1303	 (looking-at c-paren-stmt-key)
1304	 (progn (goto-char match-pos)
1305		(while (and (eq (char-before) ?\))
1306			    (c-go-list-backward))
1307		  (c-backward-syntactic-ws))
1308		(eq (char-before) ?\;))))
1309      ;; We've got an expression in "for" parens.  Remove the
1310      ;; "type" that would spuriously get fontified.
1311      (let ((elt (and (consp c-record-type-identifiers)
1312		      (assq (cadr (cddr decl-or-cast))
1313			    c-record-type-identifiers))))
1314	(when elt
1315	  (setq c-record-type-identifiers
1316		(c-delq-from-dotted-list
1317		 elt c-record-type-identifiers)))
1318	t)
1319    ;; Back up to the type to fontify the declarator(s).
1320    (goto-char (car decl-or-cast))
1321
1322    (let ((decl-list
1323	   (if (not (memq context '(nil top)))
1324	       ;; Should normally not fontify a list of
1325	       ;; declarators inside an arglist, but the first
1326	       ;; argument in the ';' separated list of a "for"
1327	       ;; statement is an exception.
1328	       (when (eq (char-before match-pos) ?\()
1329		 (save-excursion
1330		   (goto-char (1- match-pos))
1331		   (c-backward-syntactic-ws)
1332		   (and (c-simple-skip-symbol-backward)
1333			(looking-at c-paren-stmt-key))))
1334	     t))
1335	  (template-class (and (eq context '<>)
1336			       (save-excursion
1337				 (goto-char match-pos)
1338				 (c-forward-syntactic-ws)
1339				 (looking-at c-template-typename-key)))))
1340      ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1341      ;; before the first declarator if it's a list.
1342      ;; `c-font-lock-declarators' handles the rest.
1343      (when decl-list
1344	(save-excursion
1345	  (c-backward-syntactic-ws)
1346	  (unless (bobp)
1347	    (c-put-char-property (1- (point)) 'c-type
1348				 (if (cadr decl-or-cast)
1349				     'c-decl-type-start
1350				   'c-decl-id-start)))))
1351      (c-font-lock-declarators
1352       (min limit (point-max)) decl-list
1353       (not (null (cadr decl-or-cast)))
1354       (not toplev) template-class))
1355
1356    ;; A declaration has been successfully identified, so do all the
1357    ;; fontification of types and refs that've been recorded.
1358    (c-fontify-recorded-types-and-refs)
1359    nil))
1360
1361
1362(defun c-font-lock-declarations (limit)
1363  ;; Fontify all the declarations, casts and labels from the point to LIMIT.
1364  ;; Assumes that strings and comments have been fontified already.
1365  ;;
1366  ;; This function will be called from font-lock for a region bounded by POINT
1367  ;; and LIMIT, as though it were to identify a keyword for
1368  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1369  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1370  ;; Fontification".
1371  ;;
1372  ;; This function might do hidden buffer changes.
1373
1374  ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
1375  (c-skip-comments-and-strings limit)
1376  (when (< (point) limit)
1377
1378    (save-restriction
1379      (let (;; The position where `c-find-decl-spots' last stopped.
1380	    start-pos
1381	    ;; o - 'decl if we're in an arglist containing declarations
1382	    ;;   (but if `c-recognize-paren-inits' is set it might also be
1383	    ;;   an initializer arglist);
1384	    ;; o - '<> if the arglist is of angle bracket type;
1385	    ;; o - 'arglist if it's some other arglist;
1386	    ;; o - nil, if not in an arglist at all.  This includes the
1387	    ;;   parenthesized condition which follows "if", "while", etc.
1388	    context
1389	    ;; A list of starting positions of possible type declarations, or of
1390	    ;; the typedef preceding one, if any.
1391	    last-cast-end
1392	    ;; The result from `c-forward-decl-or-cast-1'.
1393	    decl-or-cast
1394	    ;; The maximum of the end positions of all the checked type
1395	    ;; decl expressions in the successfully identified
1396	    ;; declarations.  The position might be either before or
1397	    ;; after the syntactic whitespace following the last token
1398	    ;; in the type decl expression.
1399	    (max-type-decl-end 0)
1400	    ;; Same as `max-type-decl-*', but used when we're before
1401	    ;; `token-pos'.
1402	    (max-type-decl-end-before-token 0)
1403	    ;; End of <..> construct which has had c-<>-arg-sep c-type
1404	    ;; properties set within it.
1405	    (max-<>-end 0)
1406	    ;; Set according to the context to direct the heuristics for
1407	    ;; recognizing C++ templates.
1408	    c-restricted-<>-arglists
1409	    ;; Turn on recording of identifier ranges in
1410	    ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
1411	    ;; later fontification.
1412	    (c-record-type-identifiers t)
1413	    label-type
1414	    c-record-ref-identifiers
1415	    ;; Make `c-forward-type' calls mark up template arglists if
1416	    ;; it finds any.  That's necessary so that we later will
1417	    ;; stop inside them to fontify types there.
1418	    (c-parse-and-markup-<>-arglists t)
1419	    ;; The font-lock package in Emacs is known to clobber
1420	    ;; `parse-sexp-lookup-properties' (when it exists).
1421	    (parse-sexp-lookup-properties
1422	     (cc-eval-when-compile
1423	       (boundp 'parse-sexp-lookup-properties))
1424	     ))
1425
1426	;; Below we fontify a whole declaration even when it crosses the limit,
1427	;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
1428	;; time.  That is however annoying during editing, e.g. the following is
1429	;; a common situation while the first line is being written:
1430	;;
1431	;;     my_variable
1432	;;     some_other_variable = 0;
1433	;;
1434	;; font-lock will put the limit at the beginning of the second line
1435	;; here, and if we go past it we'll fontify "my_variable" as a type and
1436	;; "some_other_variable" as an identifier, and the latter will not
1437	;; correct itself until the second line is changed.  To avoid that we
1438	;; narrow to the limit if the region to fontify is a single line.
1439	(if (<= limit (c-point 'bonl))
1440	    (narrow-to-region
1441	     (point-min)
1442	     (save-excursion
1443	       ;; Narrow after any operator chars following the limit though,
1444	       ;; since those characters can be useful in recognizing a
1445	       ;; declaration (in particular the '{' that opens a function body
1446	       ;; after the header).
1447	       (goto-char limit)
1448	       (skip-chars-forward c-nonsymbol-chars)
1449	       (point))))
1450
1451	(c-find-decl-spots
1452	 limit
1453	 c-decl-start-re
1454	 (eval c-maybe-decl-faces)
1455
1456	 (lambda (match-pos inside-macro &optional toplev)
1457	   ;; Note to maintainers: don't use `limit' inside this lambda form;
1458	   ;; c-find-decl-spots sometimes narrows to less than `limit'.
1459	   (setq start-pos (point))
1460	   (when
1461	       ;; The result of the form below is true when we don't recognize a
1462	       ;; declaration or cast, and we don't recognize a "non-decl",
1463	       ;; typically a brace list.
1464	       (if (or (and (eq (get-text-property (point) 'face)
1465				'font-lock-keyword-face)
1466			    (looking-at c-not-decl-init-keywords))
1467		       (and c-macro-with-semi-re
1468			    (looking-at c-macro-with-semi-re))) ; 2008-11-04
1469		   ;; Don't do anything more if we're looking at a keyword that
1470		   ;; can't start a declaration.
1471		   t
1472
1473		 ;; Set `context' and `c-restricted-<>-arglists'.  Look for
1474		 ;; "<" for the sake of C++-style template arglists.
1475		 ;; Ignore "(" when it's part of a control flow construct
1476		 ;; (e.g. "for (").
1477		 (let ((got-context
1478			(c-get-fontification-context
1479			 match-pos
1480			 (< match-pos (if inside-macro
1481					  max-type-decl-end-before-token
1482					max-type-decl-end))
1483			 toplev)))
1484		   (setq context (car got-context)
1485			 c-restricted-<>-arglists (cdr got-context)))
1486
1487		 ;; Check we haven't missed a preceding "typedef".
1488		 (when (not (looking-at c-typedef-key))
1489		   (c-backward-syntactic-ws
1490		    (max (- (point) 1000) (point-min)))
1491		   (c-backward-token-2)
1492		   (or (looking-at c-typedef-key)
1493		       (goto-char start-pos)))
1494
1495		 ;; In QT, "more" is an irritating keyword that expands to nothing.
1496		 ;; We skip over it to prevent recognition of "more slots: <symbol>"
1497		 ;; as a bitfield declaration.
1498		 (when (and (c-major-mode-is 'c++-mode)
1499			    (looking-at
1500			     (concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)")))
1501		   (goto-char (match-end 1))
1502		   (c-forward-syntactic-ws))
1503
1504		 ;; Now analyze the construct.
1505		 (if (eq context 'not-decl)
1506		     (progn
1507		       (setq decl-or-cast nil)
1508		       (if (c-syntactic-re-search-forward
1509			    "," (min limit (point-max)) 'at-limit t)
1510			   (c-put-char-property (1- (point)) 'c-type 'c-not-decl))
1511		       nil)
1512		   (setq decl-or-cast
1513			 (c-forward-decl-or-cast-1
1514			  match-pos context last-cast-end))
1515
1516		   ;; Ensure that c-<>-arg-sep c-type properties are in place on the
1517		   ;; commas separating the arguments inside template/generic <..>s.
1518		   (when (and (eq (char-before match-pos) ?<)
1519			      (> match-pos max-<>-end))
1520		     (save-excursion
1521		       (goto-char match-pos)
1522		       (c-backward-token-2)
1523		       (if (and
1524			    (eq (char-after) ?<)
1525			    (let ((c-restricted-<>-arglists
1526				   (save-excursion
1527				     (c-backward-token-2)
1528				     (and
1529				      (not (looking-at c-opt-<>-sexp-key))
1530				      (progn
1531					(c-backward-syntactic-ws
1532					 (max (- (point) 1000) (point-min)))
1533					(memq (char-before) '(?\( ?,)))
1534				      (not (eq (c-get-char-property (1- (point))
1535								    'c-type)
1536					       'c-decl-arg-start))))))
1537			      (c-forward-<>-arglist nil)))
1538			   (setq max-<>-end (point)))))
1539
1540		   (cond
1541		    ((eq decl-or-cast 'cast)
1542		     ;; Save the position after the previous cast so we can feed
1543		     ;; it to `c-forward-decl-or-cast-1' in the next round.  That
1544		     ;; helps it discover cast chains like "(a) (b) c".
1545		     (setq last-cast-end (point))
1546		     (c-fontify-recorded-types-and-refs)
1547		     nil)
1548
1549		    (decl-or-cast
1550		     ;; We've found a declaration.
1551
1552		     ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1553		     ;; under the assumption that we're after the first type decl
1554		     ;; expression in the declaration now.  That's not really true;
1555		     ;; we could also be after a parenthesized initializer
1556		     ;; expression in C++, but this is only used as a last resort
1557		     ;; to slant ambiguous expression/declarations, and overall
1558		     ;; it's worth the risk to occasionally fontify an expression
1559		     ;; as a declaration in an initializer expression compared to
1560		     ;; getting ambiguous things in normal function prototypes
1561		     ;; fontified as expressions.
1562		     (if inside-macro
1563			 (when (> (point) max-type-decl-end-before-token)
1564			   (setq max-type-decl-end-before-token (point)))
1565		       (when (> (point) max-type-decl-end)
1566			 (setq max-type-decl-end (point))))
1567		     (goto-char start-pos)
1568		     (c-font-lock-single-decl limit decl-or-cast match-pos
1569					      context
1570					      (or toplev (nth 4 decl-or-cast))))
1571
1572		    (t t))))
1573
1574	     ;; It was a false alarm.  Check if we're in a label (or other
1575	     ;; construct with `:' except bitfield) instead.
1576	     (goto-char start-pos)
1577	     (when (setq label-type (c-forward-label t match-pos nil))
1578	       ;; Can't use `c-fontify-types-and-refs' here since we
1579	       ;; use the label face at times.
1580	       (cond ((eq label-type 'goto-target)
1581		      (c-put-font-lock-face (caar c-record-ref-identifiers)
1582					    (cdar c-record-ref-identifiers)
1583					    c-label-face-name))
1584		     ((eq label-type 'qt-1kwd-colon)
1585		      (c-put-font-lock-face (caar c-record-ref-identifiers)
1586					    (cdar c-record-ref-identifiers)
1587					    'font-lock-keyword-face))
1588		     ((eq label-type 'qt-2kwds-colon)
1589		      (mapc
1590		       (lambda (kwd)
1591			 (c-put-font-lock-face (car kwd) (cdr kwd)
1592					       'font-lock-keyword-face))
1593		       c-record-ref-identifiers)))
1594	       (setq c-record-ref-identifiers nil)
1595	       ;; `c-forward-label' has probably added a `c-decl-end'
1596	       ;; marker, so return t to `c-find-decl-spots' to signal
1597	       ;; that.
1598	       t))))
1599
1600	nil))))
1601
1602(defun c-font-lock-enum-body (limit)
1603  ;; Fontify the identifiers of each enum we find by searching forward.
1604  ;;
1605  ;; This function will be called from font-lock for a region bounded by POINT
1606  ;; and LIMIT, as though it were to identify a keyword for
1607  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1608  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1609  ;; Fontification".
1610  (while (and (< (point) limit)
1611	      (search-forward-regexp c-enum-clause-introduction-re limit t))
1612    (when (save-excursion
1613	    (backward-char)
1614	    (c-backward-over-enum-header))
1615      (c-forward-syntactic-ws)
1616      (c-font-lock-declarators limit t nil t)))
1617  nil)
1618
1619(defun c-font-lock-enum-tail (limit)
1620  ;; Fontify an enum's identifiers when POINT is within the enum's brace
1621  ;; block.
1622  ;;
1623  ;; This function will be called from font-lock for a region bounded by POINT
1624  ;; and LIMIT, as though it were to identify a keyword for
1625  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1626  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1627  ;; Fontification".
1628  ;;
1629  ;; Note that this function won't attempt to fontify beyond the end of the
1630  ;; current enum block, if any.
1631  (c-skip-comments-and-strings limit)
1632  (when (< (point) limit)
1633    (let* ((paren-state (c-parse-state))
1634	   (encl-pos (c-most-enclosing-brace paren-state)))
1635      (when (and
1636	     encl-pos
1637	     (eq (char-after encl-pos) ?\{)
1638	     (save-excursion
1639	       (goto-char encl-pos)
1640	       (c-backward-over-enum-header)))
1641	(c-syntactic-skip-backward "^{," nil t)
1642	(c-put-char-property (1- (point)) 'c-type 'c-decl-id-start)
1643
1644	(c-forward-syntactic-ws)
1645	(c-font-lock-declarators limit t nil t))))
1646  nil)
1647
1648(defun c-font-lock-cut-off-declarators (limit)
1649  ;; Fontify any declarators "cut off" from their declaring type at the start
1650  ;; of the region being fontified.
1651  ;;
1652  ;; This function will be called from font-lock- for a region bounded by
1653  ;; POINT and LIMIT, as though it were to identify a keyword for
1654  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1655  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1656  ;; fontification".
1657  (c-skip-comments-and-strings limit)
1658  (when (< (point) limit)
1659    (let ((here (point))
1660	  (decl-search-lim (c-determine-limit 1000))
1661	  paren-state encl-pos token-end context decl-or-cast
1662	  start-pos top-level c-restricted-<>-arglists
1663	  c-recognize-knr-p)		; Strictly speaking, bogus, but it
1664					; speeds up lisp.h tremendously.
1665      (save-excursion
1666	(when (not (c-back-over-member-initializers decl-search-lim))
1667	  (unless (or (eobp)
1668		      (looking-at "\\s(\\|\\s)"))
1669	    (forward-char))
1670	  (c-syntactic-skip-backward "^;{}" decl-search-lim t)
1671	  (when (eq (char-before) ?})
1672	    (c-go-list-backward)	; brace block of struct, etc.?
1673	    (c-syntactic-skip-backward "^;{}" decl-search-lim t))
1674	  (when (or (bobp)
1675		    (memq (char-before) '(?\; ?{ ?})))
1676	    (setq token-end (point))
1677	    (c-forward-syntactic-ws here)
1678	    (when (< (point) here)
1679	      ;; We're now putatively at the declaration.
1680	      (setq start-pos (point))
1681	      (setq paren-state (c-parse-state))
1682	      ;; At top level or inside a "{"?
1683	      (if (or (not (setq encl-pos
1684				 (c-most-enclosing-brace paren-state)))
1685		      (eq (char-after encl-pos) ?\{))
1686		  (progn
1687		    (setq top-level (c-at-toplevel-p))
1688		    (let ((got-context (c-get-fontification-context
1689					token-end nil top-level)))
1690		      (setq context (car got-context)
1691			    c-restricted-<>-arglists (cdr got-context)))
1692		    (setq decl-or-cast
1693			  (c-forward-decl-or-cast-1 token-end context nil))
1694		    (when (consp decl-or-cast)
1695		      (goto-char start-pos)
1696		      (c-font-lock-single-decl limit decl-or-cast token-end
1697					       context top-level))))))))
1698      nil)))
1699
1700(defun c-font-lock-enclosing-decls (limit)
1701  ;; Fontify the declarators of (nested) declarations we're in the middle of.
1702  ;; This is mainly for when a jit-lock etc. chunk starts inside the brace
1703  ;; block of a struct/union/class, etc.
1704  ;;
1705  ;; This function will be called from font-lock for a region bounded by POINT
1706  ;; and LIMIT, as though it were to identify a keyword for
1707  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1708  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1709  ;; Fontification".
1710  (c-skip-comments-and-strings limit)
1711  (when (< (point) limit)
1712    (let* ((paren-state (c-parse-state))
1713	   (decl-search-lim (c-determine-limit 1000))
1714	   in-typedef ps-elt)
1715      ;; Are we in any nested struct/union/class/etc. braces?
1716      (while paren-state
1717	(setq ps-elt (car paren-state)
1718	      paren-state (cdr paren-state))
1719	(when (and (atom ps-elt)
1720		   (eq (char-after ps-elt) ?\{))
1721	  (goto-char ps-elt)
1722	  (c-syntactic-skip-backward "^;{}" decl-search-lim)
1723	  (c-forward-syntactic-ws)
1724	  (setq in-typedef (looking-at c-typedef-key))
1725	  (if in-typedef (c-forward-over-token-and-ws))
1726	  (when (and c-opt-block-decls-with-vars-key
1727		     (looking-at c-opt-block-decls-with-vars-key))
1728	    (goto-char ps-elt)
1729	    (when (c-safe (c-forward-sexp))
1730	      (c-forward-syntactic-ws)
1731	      (c-font-lock-declarators limit t in-typedef
1732				       (not (c-bs-at-toplevel-p (point)))))))))))
1733
1734(defun c-font-lock-ml-strings (limit)
1735  ;; Fontify multi-line strings.
1736  ;;
1737  ;; This function will be called from font-lock for a region bounded by POINT
1738  ;; and LIMIT, as though it were to identify a keyword for
1739  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1740  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1741  ;; Fontification".
1742  (let* ((state (c-semi-pp-to-literal (point)))
1743	 (string-start (and (eq (cadr state) 'string)
1744			    (car (cddr state))))
1745	 (open-delim (and string-start
1746			  (save-excursion
1747			    (goto-char (1+ string-start))
1748			    (c-ml-string-opener-around-point))))
1749	 (string-delims (and open-delim
1750			     (cons open-delim (c-get-ml-closer open-delim))))
1751	 found)
1752    ;; We go round the next loop twice per raw string, once for each "end".
1753    (while (< (point) limit)
1754      (cond
1755       ;; Point is not in an ml string
1756       ((not string-delims)
1757	(while (and (setq found (re-search-forward c-ml-string-opener-re
1758						   limit 'limit))
1759		    (> (match-beginning 0) (point-min))
1760		    (memq (c-get-char-property (1- (match-beginning 0)) 'face)
1761			  '(font-lock-comment-face font-lock-string-face
1762			    font-lock-comment-delimiter-face))))
1763	(when found
1764	  (setq open-delim (cons (match-beginning 1)
1765				 (cons (match-end 1) (match-beginning 2)))
1766		string-delims (cons open-delim (c-get-ml-closer open-delim)))
1767	  (goto-char (caar string-delims))))
1768
1769       ;; Point is in the body of an ml string.
1770       ((and string-delims
1771	     (>= (point) (cadar string-delims))
1772	     (or (not (cdr string-delims))
1773		 (< (point) (cadr string-delims))))
1774	(if (cdr string-delims)
1775	    (goto-char (cadr string-delims))
1776	  (if (equal (c-get-char-property (1- (cadar string-delims))
1777					  'syntax-table)
1778		     '(15))		; "Always" the case.
1779	      ;; The next search should be successful for an unterminated ml
1780	      ;; string inside a macro, but not for any other unterminated
1781	      ;; string.
1782	      (progn
1783		(or (c-search-forward-char-property 'syntax-table '(15) limit)
1784		    (goto-char limit))
1785		(setq string-delims nil))
1786	    (c-benign-error "Missing '(15) syntax-table property at %d"
1787			    (1- (cadar string-delims)))
1788	    (setq string-delims nil))))
1789
1790       ;; Point is at or in a closing delimiter
1791       ((and string-delims
1792	     (cdr string-delims)
1793	     (>= (point) (cadr string-delims)))
1794	(c-put-font-lock-face (cadr string-delims) (1+ (cadr string-delims))
1795			      'font-lock-string-face)
1796	(c-remove-font-lock-face (1+ (cadr string-delims))
1797				 (caddr string-delims))
1798	(goto-char (caddr string-delims))
1799	(setq string-delims nil))
1800
1801       ;; point is at or in an opening delimiter.
1802       (t
1803	(if (cdr string-delims)
1804	    (progn
1805	      (c-remove-font-lock-face (caar string-delims)
1806				       (1- (cadar string-delims)))
1807	      (c-put-font-lock-face (1- (cadar string-delims))
1808				    (cadar string-delims)
1809				    'font-lock-string-face))
1810	  (c-put-font-lock-face (caar string-delims) (cadar string-delims)
1811				'font-lock-warning-face))
1812	(goto-char (cadar string-delims)))))
1813    nil))
1814
1815(defun c-font-lock-c++-lambda-captures (limit)
1816  ;; Fontify the lambda capture component of C++ lambda declarations.
1817  ;;
1818  ;; This function will be called from font-lock for a region bounded by POINT
1819  ;; and LIMIT, as though it were to identify a keyword for
1820  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
1821  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
1822  ;; Fontification".
1823  (let (mode capture-default id-start id-end declaration sub-begin sub-end)
1824    (while (and (< (point) limit)
1825		(search-forward "[" limit t))
1826      (when (progn (backward-char)
1827		   (prog1
1828		       (c-looking-at-c++-lambda-capture-list)
1829		     (forward-char)))
1830	(c-forward-syntactic-ws)
1831	(setq mode (and (memq (char-after) '(?= ?&))
1832			(char-after)))
1833	;; Is the first element of the list a bare "=" or "&"?
1834	(when mode
1835	  (forward-char)
1836	  (c-forward-syntactic-ws)
1837	  (if (memq (char-after) '(?, ?\]))
1838	      (progn
1839		(setq capture-default mode)
1840		(when (eq (char-after) ?,)
1841		  (forward-char)
1842		  (c-forward-syntactic-ws)))
1843	    (c-backward-token-2)))
1844
1845	;; Go round the following loop once per captured item.  We use "\\s)"
1846	;; rather than "\\]" here to avoid infinite looping in this situation:
1847	;; "unsigned items [] { [ }".  The second "[" triggers this function,
1848	;; but if we don't match the "}" with an "\\s)", the
1849	;; `c-syntactic-re-search-forward' at the end of the loop fails to
1850	;; move forward over it, leaving point stuck at the "}".
1851	(while (and (not (looking-at "\\s)"))
1852		    (< (point) limit))
1853	  (if (eq (char-after) ?&)
1854	      (progn (setq mode ?&)
1855		     (forward-char)
1856		     (c-forward-syntactic-ws))
1857	    (setq mode ?=))
1858	  (if (c-on-identifier)
1859	      (progn
1860		(setq id-start (point))
1861		(forward-char)
1862		(c-end-of-current-token)
1863		(setq id-end (point))
1864		(c-forward-syntactic-ws)
1865
1866		(setq declaration (eq (char-after) ?=))
1867		(when declaration
1868		  (forward-char)	; over "="
1869		  (c-forward-syntactic-ws)
1870		  (setq sub-begin (point)))
1871		(if (or (and (< (point) limit)
1872			     (c-syntactic-re-search-forward "," limit t t))
1873			(and (c-go-up-list-forward nil limit)
1874			     (eq (char-before) ?\])))
1875		    (backward-char)
1876		  (goto-char limit))
1877		(when declaration
1878		  (save-excursion
1879		    (setq sub-end (point))
1880		    (goto-char sub-begin)
1881		    (c-font-lock-c++-lambda-captures sub-end)))
1882
1883		(c-put-font-lock-face id-start id-end
1884				      (cond
1885				       (declaration
1886					'font-lock-variable-name-face)
1887				       ((and capture-default
1888					     (eq mode capture-default))
1889					'font-lock-warning-face)
1890				       ((eq mode ?=) font-lock-constant-face)
1891				       (t 'font-lock-variable-name-face))))
1892	    (c-syntactic-re-search-forward "," limit 'bound t))
1893
1894	  (c-forward-syntactic-ws)
1895	  (when (eq (char-after) ?,)
1896	    (forward-char)
1897	    (c-forward-syntactic-ws)))
1898
1899	(setq capture-default nil)
1900	(if (< (point) limit)
1901	    (forward-char))))) ; over the terminating "]" or other close paren.
1902  nil)
1903
1904
1905(c-lang-defconst c-simple-decl-matchers
1906  "Simple font lock matchers for types and declarations.  These are used
1907on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1908
1909  t `(;; Objective-C methods.
1910      ,@(when (c-major-mode-is 'objc-mode)
1911	  `((,(c-lang-const c-opt-method-key)
1912	     (,(byte-compile
1913		(lambda (limit)
1914		  (let (;; The font-lock package in Emacs is known to clobber
1915			;; `parse-sexp-lookup-properties' (when it exists).
1916			(parse-sexp-lookup-properties
1917			 (cc-eval-when-compile
1918			   (boundp 'parse-sexp-lookup-properties))))
1919		    (save-restriction
1920		      (narrow-to-region (point-min) limit)
1921		      (c-font-lock-objc-method)))
1922		  nil))
1923	      (goto-char (match-end 1))))))
1924
1925      ;; Fontify all type names and the identifiers in the
1926      ;; declarations they might start.  Use eval here since
1927      ;; `c-known-type-key' gets its value from
1928      ;; `*-font-lock-extra-types' on mode init.
1929      (eval . (list ,(c-make-font-lock-search-function
1930		      'c-known-type-key
1931		      '(1 'font-lock-type-face t)
1932		      '((c-font-lock-declarators limit t nil nil)
1933			(save-match-data
1934			  (goto-char (match-end 1))
1935			  (c-forward-syntactic-ws))
1936			(goto-char (match-end 1))))))
1937
1938      ;; Fontify types preceded by `c-type-prefix-kwds' and the
1939      ;; identifiers in the declarations they might start.
1940      ,@(when (c-lang-const c-type-prefix-kwds)
1941	  (let* ((prefix-re (c-make-keywords-re nil
1942			      (c-lang-const c-type-prefix-kwds)))
1943		 (type-match (+ 2
1944				(regexp-opt-depth prefix-re)
1945				(c-lang-const c-simple-ws-depth))))
1946	    `((,(c-make-font-lock-search-function
1947		 (concat "\\<\\(" prefix-re "\\)" ; 1
1948			 (c-lang-const c-simple-ws) "+"
1949			 (concat "\\("	; 2 + prefix-re + c-simple-ws
1950				 (c-lang-const c-symbol-key)
1951				 "\\)"))
1952		 `(,type-match
1953		   'font-lock-type-face t)
1954		 `((c-font-lock-declarators limit t nil nil)
1955		   (save-match-data
1956		     (goto-char (match-end ,type-match))
1957		     (c-forward-syntactic-ws))
1958		   (goto-char (match-end ,type-match))))))))
1959
1960      ;; Fontify special declarations that lacks a type.
1961      ,@(when (c-lang-const c-typeless-decl-kwds)
1962	  `((,(c-make-font-lock-search-function
1963	       (concat "\\<\\("
1964		       (regexp-opt (c-lang-const c-typeless-decl-kwds))
1965		       "\\)\\>")
1966	       '((c-font-lock-declarators limit t nil nil)
1967		 (save-match-data
1968		   (goto-char (match-end 1))
1969		   (c-forward-syntactic-ws))
1970		 (goto-char (match-end 1)))))))
1971
1972      ;; Fontify generic colon labels in languages that support them.
1973      ,@(when (c-lang-const c-recognize-colon-labels)
1974	  '(c-font-lock-labels))))
1975
1976(c-lang-defconst c-complex-decl-matchers
1977  "Complex font lock matchers for types and declarations.  Used on level
19783 and higher."
1979
1980  ;; Note: This code in this form dumps a number of functions into the
1981  ;; resulting constant, `c-matchers-3'.  At run time, font lock will call
1982  ;; each of them as a "FUNCTION" (see Elisp page "Search-based
1983  ;; Fontification").  The font lock region is delimited by POINT and the
1984  ;; single parameter, LIMIT.  Each of these functions returns NIL (thus
1985  ;; inhibiting spurious font-lock-keyword-face highlighting and another
1986  ;; call).
1987
1988  t `(;; Initialize some things before the search functions below.
1989      c-font-lock-complex-decl-prepare
1990
1991      ,@(if (c-major-mode-is 'objc-mode)
1992	    ;; Fontify method declarations in Objective-C, but first
1993	    ;; we have to put the `c-decl-end' `c-type' property on
1994	    ;; all the @-style directives that haven't been handled in
1995	    ;; `c-basic-matchers-before'.
1996	    `(,(c-make-font-lock-search-function
1997		(c-make-keywords-re t
1998		  ;; Exclude "@class" since that directive ends with a
1999		  ;; semicolon anyway.
2000		  (delete "@class"
2001			  (append (c-lang-const c-protection-kwds)
2002				  (c-lang-const c-other-decl-kwds)
2003				  nil)))
2004		'((c-put-char-property (1- (match-end 1))
2005				       'c-type 'c-decl-end)))
2006	      c-font-lock-objc-methods))
2007
2008      ;; Fontify declarators which have been cut off from their declaring
2009      ;; types at the start of the region.
2010      c-font-lock-cut-off-declarators
2011
2012      ;; Fontify all declarations, casts and normal labels.
2013      c-font-lock-declarations
2014
2015      ;; Fontify declarators when POINT is within their declaration.
2016      c-font-lock-enclosing-decls
2017
2018      ;; Fontify angle bracket arglists like templates in C++.
2019      ,@(when (c-lang-const c-recognize-<>-arglists)
2020	  '(c-font-lock-<>-arglists))
2021
2022      ,@(when (c-major-mode-is 'c++-mode)
2023	  '(c-font-lock-c++-lambda-captures))
2024
2025      ,@(when (c-lang-const c-using-key)
2026	  `(c-font-lock-c++-using))
2027
2028      ;; The first two rules here mostly find occurrences that
2029      ;; `c-font-lock-declarations' has found already, but not
2030      ;; declarations containing blocks in the type (see note below).
2031      ;; It's also useful to fontify these everywhere to show e.g. when
2032      ;; a type keyword is accidentally used as an identifier.
2033
2034      ;; Fontify basic types.
2035      ,(let ((re (c-make-keywords-re nil
2036		   (c-lang-const c-primitive-type-kwds))))
2037	 (if (c-major-mode-is 'pike-mode)
2038	     ;; No symbol is a keyword after "->" in Pike.
2039	     `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
2040			"\\<\\(" re "\\)\\>")
2041	       2 font-lock-type-face)
2042	   `(,(concat "\\<\\(" re "\\)\\>")
2043	     1 'font-lock-type-face)))
2044      ;; Fontify the type in C++ "new" expressions.
2045      ,@(when (c-major-mode-is 'c++-mode)
2046	  ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)"
2047	  ;; (see Elisp page "Search-based Fontification").
2048	  '(("\\<new\\>"
2049	     (c-font-lock-c++-new))))
2050      ))
2051
2052(defun c-font-lock-labels (limit)
2053  ;; Fontify all statement labels from the point to LIMIT.  Assumes
2054  ;; that strings and comments have been fontified already.  Nil is
2055  ;; always returned.
2056  ;;
2057  ;; Note: This function is only used on decoration level 2; this is
2058  ;; taken care of directly by the gargantuan
2059  ;; `c-font-lock-declarations' on higher levels.
2060  ;;
2061  ;; This function might do hidden buffer changes.
2062
2063  (let (continue-pos id-start
2064	;; The font-lock package in Emacs is known to clobber
2065	;; `parse-sexp-lookup-properties' (when it exists).
2066	(parse-sexp-lookup-properties
2067	 (cc-eval-when-compile
2068	   (boundp 'parse-sexp-lookup-properties))))
2069
2070    (while (re-search-forward ":[^:]" limit t)
2071      (setq continue-pos (point))
2072      (goto-char (match-beginning 0))
2073      (unless (c-skip-comments-and-strings limit)
2074
2075	(c-backward-syntactic-ws)
2076	(and (setq id-start (c-on-identifier))
2077
2078	     (not (get-text-property id-start 'face))
2079
2080	     (progn
2081	       (goto-char id-start)
2082	       (c-backward-syntactic-ws)
2083	       (or
2084		;; Check for a char that precedes a statement.
2085		(memq (char-before) '(?\} ?\{ ?\;))
2086		;; Check for a preceding label.  We exploit the font
2087		;; locking made earlier by this function.
2088		(and (eq (char-before) ?:)
2089		     (progn
2090		       (backward-char)
2091		       (c-backward-syntactic-ws)
2092		       (not (bobp)))
2093		     (eq (get-text-property (1- (point)) 'face)
2094			 c-label-face-name))
2095		;; Check for a keyword that precedes a statement.
2096		(c-after-conditional)))
2097
2098	     (progn
2099	       ;; Got a label.
2100	       (goto-char id-start)
2101	       (looking-at c-symbol-key)
2102	       (c-put-font-lock-face (match-beginning 0) (match-end 0)
2103				     c-label-face-name)))
2104
2105	(goto-char continue-pos))))
2106  nil)
2107
2108(c-lang-defconst c-basic-matchers-after
2109  "Font lock matchers for various things that should be fontified after
2110generic casts and declarations are fontified.  Used on level 2 and
2111higher."
2112
2113  t `(,@(when (c-lang-const c-brace-list-decl-kwds)
2114      ;; Fontify the remaining identifiers inside an enum list when we start
2115      ;; inside it.
2116	  '(c-font-lock-enum-tail
2117	    ;; Fontify the identifiers inside enum lists.  (The enum type
2118	    ;; name is handled by `c-simple-decl-matchers' or
2119	    ;; `c-complex-decl-matchers' below.
2120	    c-font-lock-enum-body))
2121
2122	;; Fontify labels after goto etc.
2123	,@(when (c-lang-const c-before-label-kwds)
2124	  `(;; (Got three different interpretation levels here,
2125	    ;; which makes it a bit complicated: 1) The backquote
2126	    ;; stuff is expanded when compiled or loaded, 2) the
2127	    ;; eval form is evaluated at font-lock setup (to
2128	    ;; substitute c-label-face-name correctly), and 3) the
2129	    ;; resulting structure is interpreted during
2130	    ;; fontification.)
2131	    (eval
2132	     . ,(let* ((c-before-label-re
2133			(c-make-keywords-re nil
2134			  (c-lang-const c-before-label-kwds))))
2135		  `(list
2136		    ,(concat "\\<\\(" c-before-label-re "\\)\\>"
2137			     "\\s *"
2138			     "\\("	; identifier-offset
2139			     (c-lang-const c-symbol-key)
2140			     "\\)")
2141		    (list ,(+ (regexp-opt-depth c-before-label-re) 2)
2142			  c-label-face-name nil t))))))
2143
2144      ;; Fontify the clauses after various keywords.
2145	,@(when (or (c-lang-const c-type-list-kwds)
2146		    (c-lang-const c-ref-list-kwds)
2147		    (c-lang-const c-colon-type-list-kwds))
2148	    `((,(c-make-font-lock-BO-decl-search-function
2149		 (concat "\\<\\("
2150			 (c-make-keywords-re nil
2151			   (append (c-lang-const c-type-list-kwds)
2152				   (c-lang-const c-ref-list-kwds)
2153				   (c-lang-const c-colon-type-list-kwds)))
2154			 "\\)\\>")
2155		 '((c-fontify-types-and-refs ((c-promote-possible-types t))
2156		     (c-forward-keyword-clause 1)
2157		     (if (> (point) limit) (goto-char limit))))))))
2158
2159	,@(when (c-lang-const c-paren-type-kwds)
2160	    `((,(c-make-font-lock-search-function
2161		 (concat "\\<\\("
2162			 (c-make-keywords-re nil
2163			   (c-lang-const c-paren-type-kwds))
2164			 "\\)\\>")
2165		 '((c-fontify-types-and-refs ((c-promote-possible-types t))
2166		     (c-forward-keyword-clause 1)
2167		     (if (> (point) limit) (goto-char limit))))))))
2168
2169	,@(when (c-major-mode-is 'java-mode)
2170	    '((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face))))
2171      ))
2172
2173(c-lang-defconst c-matchers-1
2174  t (c-lang-const c-cpp-matchers))
2175
2176(c-lang-defconst c-matchers-2
2177  t (append (c-lang-const c-matchers-1)
2178	    (c-lang-const c-basic-matchers-before)
2179	    (c-lang-const c-simple-decl-matchers)
2180	    (c-lang-const c-basic-matchers-after)))
2181
2182(c-lang-defconst c-matchers-3
2183  t (append (c-lang-const c-matchers-1)
2184	    (c-lang-const c-basic-matchers-before)
2185	    (c-lang-const c-complex-decl-matchers)
2186	    (c-lang-const c-basic-matchers-after)))
2187
2188(defun c-get-doc-comment-style ()
2189  ;; Get the symbol (or list of symbols) constituting the document style.
2190  ;; Return nil if there is no such, otherwise something like `autodoc'.
2191  (if (consp (car-safe c-doc-comment-style))
2192      (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
2193		    (assq 'other c-doc-comment-style)))
2194    c-doc-comment-style))
2195
2196(defun c-compose-keywords-list (base-list)
2197  ;; Incorporate the font lock keyword lists according to
2198  ;; `c-doc-comment-style' on the given keyword list and return it.
2199  ;; This is used in the function bindings of the
2200  ;; `*-font-lock-keywords-*' symbols since we have to build the list
2201  ;; when font-lock is initialized.
2202
2203  (unless (memq c-doc-face-name c-literal-faces)
2204    (setq c-literal-faces (cons c-doc-face-name c-literal-faces)))
2205
2206  (let* ((doc-keywords (c-get-doc-comment-style))
2207	 (list (nconc (c--mapcan
2208		       (lambda (doc-style)
2209			 (let ((sym (intern
2210				     (concat (symbol-name doc-style)
2211					     "-font-lock-keywords"))))
2212			   (cond ((fboundp sym)
2213				  (funcall sym))
2214				 ((boundp sym)
2215				  (append (eval sym) nil)))))
2216		       (if (listp doc-keywords)
2217			   doc-keywords
2218			 (list doc-keywords)))
2219		      base-list)))
2220
2221    ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we
2222    ;; move it first since the doc comment font lockers might add
2223    ;; `c-type' text properties, so they have to be cleared before that.
2224    (when (memq 'c-font-lock-complex-decl-prepare list)
2225      (setq list (cons 'c-font-lock-complex-decl-prepare
2226		       (delq 'c-font-lock-complex-decl-prepare
2227			     (append list nil)))))
2228
2229    list))
2230
2231(defun c-override-default-keywords (def-var)
2232  ;; This is used to override the value on a `*-font-lock-keywords'
2233  ;; variable only if it's nil or has the same value as one of the
2234  ;; `*-font-lock-keywords-*' variables.  Older font-lock packages
2235  ;; define a default value for `*-font-lock-keywords' which we want
2236  ;; to override, but we should otoh avoid clobbering a user setting.
2237  ;; This heuristic for that isn't perfect, but I can't think of any
2238  ;; better. /mast
2239  (when (and (boundp def-var)
2240	     (memq (symbol-value def-var)
2241		   (cons nil
2242			 (mapcar
2243			  (lambda (suffix)
2244			    (let ((sym (intern (concat (symbol-name def-var)
2245						       suffix))))
2246			      (and (boundp sym) (symbol-value sym))))
2247			  '("-1" "-2" "-3")))))
2248    ;; The overriding is done by unbinding the variable so that the normal
2249    ;; defvar will install its default value later on.
2250    (makunbound def-var)))
2251
2252;; `c-re-redisplay-timer' is a timer which, when triggered, causes a
2253;; redisplay.
2254(defvar c-re-redisplay-timer nil)
2255
2256(defun c-force-redisplay (start end)
2257  ;; Force redisplay immediately.  This assumes `font-lock-support-mode' is
2258  ;; 'jit-lock-mode.  Set the variable `c-re-redisplay-timer' to nil.
2259  (save-excursion (c-font-lock-fontify-region start end))
2260  (jit-lock-force-redisplay (copy-marker start) (copy-marker end))
2261  (setq c-re-redisplay-timer nil))
2262
2263(defun c-fontify-new-found-type (type)
2264  ;; Cause the fontification of TYPE, a string, wherever it occurs in the
2265  ;; buffer.  If TYPE is currently displayed in a window, cause redisplay to
2266  ;; happen "instantaneously".  These actions are done only when jit-lock-mode
2267  ;; is active.
2268  (when (and font-lock-mode
2269	     (boundp 'font-lock-support-mode)
2270	     (eq font-lock-support-mode 'jit-lock-mode))
2271    (c-save-buffer-state
2272	((window-boundaries
2273	  (mapcar (lambda (win)
2274		    (cons (window-start win)
2275			  (window-end win)))
2276		  (get-buffer-window-list (current-buffer) 'no-mini t)))
2277	 (target-re (concat "\\_<" type "\\_>")))
2278      (save-excursion
2279	(save-restriction
2280	  (widen)
2281	  (goto-char (point-min))
2282	  (while (re-search-forward target-re nil t)
2283	    (put-text-property (match-beginning 0) (match-end 0)
2284			       'fontified nil)
2285	    (dolist (win-boundary window-boundaries)
2286	      (when (and (< (match-beginning 0) (cdr win-boundary))
2287			 (> (match-end 0) (car win-boundary))
2288			 (not c-re-redisplay-timer))
2289		(setq c-re-redisplay-timer
2290		      (run-with-timer 0 nil #'c-force-redisplay
2291				      (match-beginning 0) (match-end 0)))))))))))
2292
2293
2294;;; C.
2295
2296(c-override-default-keywords 'c-font-lock-keywords)
2297
2298(defconst c-font-lock-keywords-1 (c-lang-const c-matchers-1 c)
2299  "Minimal font locking for C mode.
2300Fontifies only preprocessor directives (in addition to the syntactic
2301fontification of strings and comments).")
2302
2303(defconst c-font-lock-keywords-2 (c-lang-const c-matchers-2 c)
2304  "Fast normal font locking for C mode.
2305In addition to `c-font-lock-keywords-1', this adds fontification of
2306keywords, simple types, declarations that are easy to recognize, the
2307user defined types on `c-font-lock-extra-types', and the doc comment
2308styles specified by `c-doc-comment-style'.")
2309
2310(defconst c-font-lock-keywords-3 (c-lang-const c-matchers-3 c)
2311  "Accurate normal font locking for C mode.
2312Like the variable `c-font-lock-keywords-2' but detects declarations in a more
2313accurate way that works in most cases for arbitrary types without the
2314need for `c-font-lock-extra-types'.")
2315
2316(defvar c-font-lock-keywords c-font-lock-keywords-3
2317  "Default expressions to highlight in C mode.")
2318
2319(defun c-font-lock-keywords-2 ()
2320  (c-compose-keywords-list c-font-lock-keywords-2))
2321(defun c-font-lock-keywords-3 ()
2322  (c-compose-keywords-list c-font-lock-keywords-3))
2323(defun c-font-lock-keywords ()
2324  (c-compose-keywords-list c-font-lock-keywords))
2325
2326
2327;;; C++.
2328(defun c-font-lock-c++-using (limit)
2329  ;; Fontify any clauses starting with the keyword `using'.
2330  ;;
2331  ;; This function will be called from font-lock- for a region bounded by
2332  ;; POINT and LIMIT, as though it were to identify a keyword for
2333  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
2334  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
2335  ;; fontification".
2336  (let (pos)
2337    (while (c-syntactic-re-search-forward c-using-key limit 'end)
2338      (while  ; Do one declarator of a comma separated list, each time around.
2339	  (progn
2340	    (c-forward-syntactic-ws)
2341	    (setq pos (point))		; token after "using".
2342	    (when (and (c-on-identifier)
2343		       (c-forward-name))
2344	      (cond
2345	       ((eq (char-after) ?=)		; using foo = <type-id>;
2346		(goto-char pos)
2347		(c-font-lock-declarators limit nil t nil))
2348	       ((save-excursion
2349		  (and c-colon-type-list-re
2350		       (c-go-up-list-backward)
2351		       (eq (char-after) ?{)
2352		       (eq (car (c-beginning-of-decl-1
2353				 (c-determine-limit 1000)))
2354			   'same)
2355		       (looking-at c-colon-type-list-re)))
2356		;; Inherited protected member: leave unfontified
2357		)
2358	       (t (goto-char pos)
2359		  (c-font-lock-declarators limit nil c-label-face-name nil)))
2360	      (eq (char-after) ?,)))
2361	(forward-char)))		; over the comma.
2362    nil))
2363
2364(defun c-font-lock-c++-new (limit)
2365  ;; FIXME!!!  Put in a comment about the context of this function's
2366  ;; invocation.  I think it's called as an ANCHORED-MATCHER within an
2367  ;; ANCHORED-HIGHLIGHTER.  (2007/2/10).
2368  ;;
2369  ;; Assuming point is after a "new" word, check that it isn't inside
2370  ;; a string or comment, and if so try to fontify the type in the
2371  ;; allocation expression.  Nil is always returned.
2372  ;;
2373  ;; As usual, C++ takes the prize in coming up with a hard to parse
2374  ;; syntax. :P
2375  ;;
2376  ;; This function might do hidden buffer changes.
2377
2378  (unless (c-skip-comments-and-strings limit)
2379    (save-excursion
2380      (catch 'false-alarm
2381	;; A "new" keyword is followed by one to three expressions, where
2382	;; the type is the middle one, and the only required part.
2383	(let (expr1-pos expr2-pos
2384	      ;; Enable recording of identifier ranges in `c-forward-type'
2385	      ;; etc for later fontification.  Not using
2386	      ;; `c-fontify-types-and-refs' here since the ranges should
2387	      ;; be fontified selectively only when an allocation
2388	      ;; expression is successfully recognized.
2389	      (c-record-type-identifiers t)
2390	      c-record-ref-identifiers
2391	      ;; The font-lock package in Emacs is known to clobber
2392	      ;; `parse-sexp-lookup-properties' (when it exists).
2393	      (parse-sexp-lookup-properties
2394	       (cc-eval-when-compile
2395		 (boundp 'parse-sexp-lookup-properties))))
2396	  (c-forward-syntactic-ws)
2397
2398	  ;; The first placement arglist is always parenthesized, if it
2399	  ;; exists.
2400	  (when (eq (char-after) ?\()
2401	    (setq expr1-pos (1+ (point)))
2402	    (condition-case nil
2403		(c-forward-sexp)
2404	      (scan-error (throw 'false-alarm t)))
2405	    (c-forward-syntactic-ws))
2406
2407	  ;; The second expression is either a type followed by some "*" or
2408	  ;; "[...]" or similar, or a parenthesized type followed by a full
2409	  ;; identifierless declarator.
2410	  (setq expr2-pos (1+ (point)))
2411	  (cond ((eq (char-after) ?\())
2412		((let ((c-promote-possible-types t))
2413		   (c-forward-type)))
2414		(t (setq expr2-pos nil)))
2415
2416	  (when expr1-pos
2417	    (cond
2418	     ((not expr2-pos)
2419	      ;; No second expression, so the first has to be a
2420	      ;; parenthesized type.
2421	      (goto-char expr1-pos)
2422	      (let ((c-promote-possible-types t))
2423		(c-forward-type)))
2424
2425	     ((eq (char-before expr2-pos) ?\()
2426	      ;; Got two parenthesized expressions, so we have to look
2427	      ;; closer at them to decide which is the type.  No need to
2428	      ;; handle `c-record-ref-identifiers' since all references
2429	      ;; have already been handled by other fontification rules.
2430	      (let (expr1-res expr2-res)
2431
2432		(goto-char expr1-pos)
2433		(when (setq expr1-res (c-forward-type))
2434		  (unless (looking-at
2435			   (cc-eval-when-compile
2436			     (concat (c-lang-const c-symbol-start c++)
2437				     "\\|[*:)[]")))
2438		    ;; There's something after the would-be type that
2439		    ;; can't be there, so this is a placement arglist.
2440		    (setq expr1-res nil)))
2441
2442		(goto-char expr2-pos)
2443		(when (setq expr2-res (c-forward-type))
2444		  (unless (looking-at
2445			   (cc-eval-when-compile
2446			     (concat (c-lang-const c-symbol-start c++)
2447				     "\\|[*:)[]")))
2448		    ;; There's something after the would-be type that can't
2449		    ;; be there, so this is an initialization expression.
2450		    (setq expr2-res nil))
2451		  (when (and (c-go-up-list-forward)
2452			     (progn (c-forward-syntactic-ws)
2453				    (eq (char-after) ?\()))
2454		    ;; If there's a third initialization expression
2455		    ;; then the second one is the type, so demote the
2456		    ;; first match.
2457		    (setq expr1-res nil)))
2458
2459		;; We fontify the most likely type, with a preference for
2460		;; the first argument since a placement arglist is more
2461		;; unusual than an initializer.
2462		(cond ((memq expr1-res '(t known prefix)))
2463		      ((memq expr2-res '(t known prefix)))
2464		      ;; Presumably 'decltype's will be fontified elsewhere.
2465		      ((eq expr1-res 'decltype))
2466		      ((eq expr2-res 'decltype))
2467		      ((eq expr1-res 'found)
2468		       (let ((c-promote-possible-types t))
2469			 (goto-char expr1-pos)
2470			 (c-forward-type)))
2471		      ((eq expr2-res 'found)
2472		       (let ((c-promote-possible-types t))
2473			 (goto-char expr2-pos)
2474			 (c-forward-type)))
2475		      ((and (eq expr1-res 'maybe) (not expr2-res))
2476		       (let ((c-promote-possible-types t))
2477			 (goto-char expr1-pos)
2478			 (c-forward-type)))
2479		      ((and (not expr1-res) (eq expr2-res 'maybe))
2480		       (let ((c-promote-possible-types t))
2481			 (goto-char expr2-pos)
2482			 (c-forward-type)))
2483		      ;; If both type matches are 'maybe then we're
2484		      ;; too uncertain to promote either of them.
2485		      )))))
2486
2487	  ;; Fontify the type that now is recorded in
2488	  ;; `c-record-type-identifiers', if any.
2489	  (c-fontify-recorded-types-and-refs)))))
2490  nil)
2491
2492(c-override-default-keywords 'c++-font-lock-keywords)
2493
2494(defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++)
2495  "Minimal font locking for C++ mode.
2496Fontifies only preprocessor directives (in addition to the syntactic
2497fontification of strings and comments).")
2498
2499(defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++)
2500  "Fast normal font locking for C++ mode.
2501In addition to `c++-font-lock-keywords-1', this adds fontification of
2502keywords, simple types, declarations that are easy to recognize, the
2503user defined types on `c++-font-lock-extra-types', and the doc comment
2504styles specified by `c-doc-comment-style'.")
2505
2506(defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++)
2507  "Accurate normal font locking for C++ mode.
2508Like the variable `c++-font-lock-keywords-2' but detects declarations in a more
2509accurate way that works in most cases for arbitrary types without the
2510need for `c++-font-lock-extra-types'.")
2511
2512(defvar c++-font-lock-keywords c++-font-lock-keywords-3
2513  "Default expressions to highlight in C++ mode.")
2514
2515(defun c++-font-lock-keywords-2 ()
2516  (c-compose-keywords-list c++-font-lock-keywords-2))
2517(defun c++-font-lock-keywords-3 ()
2518  (c-compose-keywords-list c++-font-lock-keywords-3))
2519(defun c++-font-lock-keywords ()
2520  (c-compose-keywords-list c++-font-lock-keywords))
2521
2522
2523;;; Objective-C.
2524
2525(defun c-font-lock-objc-method ()
2526  ;; Assuming the point is after the + or - that starts an Objective-C
2527  ;; method declaration, fontify it.  This must be done before normal
2528  ;; casts, declarations and labels are fontified since they will get
2529  ;; false matches in these things.
2530  ;;
2531  ;; This function might do hidden buffer changes.
2532
2533  (c-fontify-types-and-refs
2534      ((first t)
2535       (c-promote-possible-types t))
2536
2537    (while (and
2538	    (progn
2539	      (c-forward-syntactic-ws)
2540
2541	      ;; An optional method type.
2542	      (if (eq (char-after) ?\()
2543		  (progn
2544		    (forward-char)
2545		    (c-forward-syntactic-ws)
2546		    (c-forward-type)
2547		    (prog1 (c-go-up-list-forward)
2548		      (c-forward-syntactic-ws)))
2549		t))
2550
2551	    ;; The name.  The first time it's the first part of
2552	    ;; the function name, the rest of the time it's an
2553	    ;; argument name.
2554	    (looking-at c-symbol-key)
2555	    (progn
2556	      (goto-char (match-end 0))
2557	      (c-put-font-lock-face (match-beginning 0)
2558				    (point)
2559				    (if first
2560					'font-lock-function-name-face
2561				      'font-lock-variable-name-face))
2562	      (c-forward-syntactic-ws)
2563
2564	      ;; Another optional part of the function name.
2565	      (when (looking-at c-symbol-key)
2566		(goto-char (match-end 0))
2567		(c-put-font-lock-face (match-beginning 0)
2568				      (point)
2569				      'font-lock-function-name-face)
2570		(c-forward-syntactic-ws))
2571
2572	      ;; There's another argument if a colon follows.
2573	      (eq (char-after) ?:)))
2574      (forward-char)
2575      (setq first nil))))
2576
2577(defun c-font-lock-objc-methods (limit)
2578  ;; Fontify method declarations in Objective-C.  Nil is always
2579  ;; returned.
2580  ;;
2581  ;; This function might do hidden buffer changes.
2582
2583  (let (;; The font-lock package in Emacs is known to clobber
2584	;; `parse-sexp-lookup-properties' (when it exists).
2585	(parse-sexp-lookup-properties
2586	 (cc-eval-when-compile
2587	   (boundp 'parse-sexp-lookup-properties))))
2588
2589    (c-find-decl-spots
2590     limit
2591     "[-+]"
2592     nil
2593     (lambda (_match-pos _inside-macro &optional _top-level)
2594       (forward-char)
2595       (c-font-lock-objc-method))))
2596  nil)
2597
2598(c-override-default-keywords 'objc-font-lock-keywords)
2599
2600(defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc)
2601  "Minimal font locking for Objective-C mode.
2602Fontifies only compiler directives (in addition to the syntactic
2603fontification of strings and comments).")
2604
2605(defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc)
2606  "Fast normal font locking for Objective-C mode.
2607In addition to `objc-font-lock-keywords-1', this adds fontification of
2608keywords, simple types, declarations that are easy to recognize, the
2609user defined types on `objc-font-lock-extra-types', and the doc
2610comment styles specified by `c-doc-comment-style'.")
2611
2612(defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc)
2613  "Accurate normal font locking for Objective-C mode.
2614Like the variable `objc-font-lock-keywords-2' but detects declarations in a more
2615accurate way that works in most cases for arbitrary types without the
2616need for `objc-font-lock-extra-types'.")
2617
2618(defvar objc-font-lock-keywords objc-font-lock-keywords-3
2619  "Default expressions to highlight in Objective-C mode.")
2620
2621(defun objc-font-lock-keywords-2 ()
2622  (c-compose-keywords-list objc-font-lock-keywords-2))
2623(defun objc-font-lock-keywords-3 ()
2624  (c-compose-keywords-list objc-font-lock-keywords-3))
2625(defun objc-font-lock-keywords ()
2626  (c-compose-keywords-list objc-font-lock-keywords))
2627
2628;; Kludge to override the default value that
2629;; `objc-font-lock-extra-types' might have gotten from the font-lock
2630;; package.  The value replaced here isn't relevant now anyway since
2631;; those types are builtin and therefore listed directly in
2632;; `c-primitive-type-kwds'.
2633(when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp)
2634	     '("BOOL" "Class" "IMP" "SEL"))
2635  (setq objc-font-lock-extra-types
2636	(cc-eval-when-compile (list (concat "[" c-upper "]\\sw*")))))
2637
2638
2639;;; Java.
2640
2641(c-override-default-keywords 'java-font-lock-keywords)
2642
2643(defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java)
2644  "Minimal font locking for Java mode.
2645Fontifies nothing except the syntactic fontification of strings and
2646comments.")
2647
2648(defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java)
2649  "Fast normal font locking for Java mode.
2650In addition to `java-font-lock-keywords-1', this adds fontification of
2651keywords, simple types, declarations that are easy to recognize, the
2652user defined types on `java-font-lock-extra-types', and the doc
2653comment styles specified by `c-doc-comment-style'.")
2654
2655(defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java)
2656  "Accurate normal font locking for Java mode.
2657Like variable `java-font-lock-keywords-2' but detects declarations in a more
2658accurate way that works in most cases for arbitrary types without the
2659need for `java-font-lock-extra-types'.")
2660
2661(defvar java-font-lock-keywords java-font-lock-keywords-3
2662  "Default expressions to highlight in Java mode.")
2663
2664(defun java-font-lock-keywords-2 ()
2665  (c-compose-keywords-list java-font-lock-keywords-2))
2666(defun java-font-lock-keywords-3 ()
2667  (c-compose-keywords-list java-font-lock-keywords-3))
2668(defun java-font-lock-keywords ()
2669  (c-compose-keywords-list java-font-lock-keywords))
2670
2671
2672;;; CORBA IDL.
2673
2674(c-override-default-keywords 'idl-font-lock-keywords)
2675
2676(defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl)
2677  "Minimal font locking for CORBA IDL mode.
2678Fontifies nothing except the syntactic fontification of strings and
2679comments.")
2680
2681(defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl)
2682  "Fast normal font locking for CORBA IDL mode.
2683In addition to `idl-font-lock-keywords-1', this adds fontification of
2684keywords, simple types, declarations that are easy to recognize, the
2685user defined types on `idl-font-lock-extra-types', and the doc comment
2686styles specified by `c-doc-comment-style'.")
2687
2688(defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl)
2689  "Accurate normal font locking for CORBA IDL mode.
2690Like the variable `idl-font-lock-keywords-2' but detects declarations in a more
2691accurate way that works in most cases for arbitrary types without the
2692need for `idl-font-lock-extra-types'.")
2693
2694(defvar idl-font-lock-keywords idl-font-lock-keywords-3
2695  "Default expressions to highlight in CORBA IDL mode.")
2696
2697(defun idl-font-lock-keywords-2 ()
2698  (c-compose-keywords-list idl-font-lock-keywords-2))
2699(defun idl-font-lock-keywords-3 ()
2700  (c-compose-keywords-list idl-font-lock-keywords-3))
2701(defun idl-font-lock-keywords ()
2702  (c-compose-keywords-list idl-font-lock-keywords))
2703
2704
2705;;; Pike.
2706
2707(c-override-default-keywords 'pike-font-lock-keywords)
2708
2709(defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike)
2710  "Minimal font locking for Pike mode.
2711Fontifies only preprocessor directives (in addition to the syntactic
2712fontification of strings and comments).")
2713
2714(defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike)
2715  "Fast normal font locking for Pike mode.
2716In addition to `pike-font-lock-keywords-1', this adds fontification of
2717keywords, simple types, declarations that are easy to recognize, the
2718user defined types on `pike-font-lock-extra-types', and the doc
2719comment styles specified by `c-doc-comment-style'.")
2720
2721(defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike)
2722  "Accurate normal font locking for Pike mode.
2723Like the variable `pike-font-lock-keywords-2' but detects declarations in a more
2724accurate way that works in most cases for arbitrary types without the
2725need for `pike-font-lock-extra-types'.")
2726
2727(defvar pike-font-lock-keywords pike-font-lock-keywords-3
2728  "Default expressions to highlight in Pike mode.")
2729
2730(defun pike-font-lock-keywords-2 ()
2731  (c-set-doc-comment-res)
2732  (c-compose-keywords-list pike-font-lock-keywords-2))
2733(defun pike-font-lock-keywords-3 ()
2734  (c-set-doc-comment-res)
2735  (c-compose-keywords-list pike-font-lock-keywords-3))
2736(defun pike-font-lock-keywords ()
2737  (c-set-doc-comment-res)
2738  (c-compose-keywords-list pike-font-lock-keywords))
2739
2740
2741;;; Doc comments.
2742
2743(cc-bytecomp-defvar c-doc-line-join-re)
2744;; matches a join of two lines in a doc comment.
2745;; This should not be changed directly, but instead set by
2746;; `c-setup-doc-comment-style'.  This variable is used in `c-find-decl-spots'
2747;; in (e.g.) autodoc style comments to bridge the gap between a "@\n" at an
2748;; EOL and the token following "//!" on the next line.
2749
2750(cc-bytecomp-defvar c-doc-bright-comment-start-re)
2751;; Matches the start of a "bright" comment, one whose contents may be
2752;; fontified by, e.g., `c-font-lock-declarations'.
2753
2754(cc-bytecomp-defvar c-doc-line-join-end-ch)
2755;; A list of characters, each being a last character of a doc comment marker,
2756;; e.g. the ! from pike autodoc's "//!".
2757
2758(defmacro c-set-doc-comment-re-element (suffix)
2759  ;; Set the variable `c-doc-line-join-re' to a buffer local value suitable
2760  ;; for the current doc comment style, or kill the local value.
2761  (declare (debug t))
2762  (let ((var (intern (concat "c-doc" suffix))))
2763    `(let* ((styles (c-get-doc-comment-style))
2764	    elts)
2765       (when (atom styles)
2766	 (setq styles (list styles)))
2767       (setq elts
2768	     (mapcar (lambda (style)
2769		       (let ((sym
2770			      (intern-soft
2771			       (concat (symbol-name style) ,suffix))))
2772			 (and sym
2773			      (boundp sym)
2774			      (symbol-value sym))))
2775		     styles))
2776       (setq elts (delq nil elts))
2777       (setq elts (and elts
2778		       (concat "\\("
2779			       (mapconcat #'identity elts "\\|")
2780			       "\\)")))
2781       (if elts
2782	   (set (make-local-variable ',var) elts)
2783	 (kill-local-variable ',var)))))
2784
2785(defmacro c-set-doc-comment-char-list (suffix)
2786  ;; Set the variable 'c-doc-<suffix>' to the list of *-<suffix>, which must
2787  ;; be characters, and * represents the doc comment style.
2788  (declare (debug t))
2789  (let ((var (intern (concat "c-doc" suffix))))
2790    `(let* ((styles (c-get-doc-comment-style))
2791	    elts)
2792       (when (atom styles)
2793	 (setq styles (list styles)))
2794       (setq elts
2795	     (mapcar (lambda (style)
2796		       (let ((sym
2797			      (intern-soft
2798			       (concat (symbol-name style) ,suffix))))
2799			 (and sym
2800			      (boundp sym)
2801			      (symbol-value sym))))
2802		     styles))
2803       (setq elts (delq nil elts))
2804       (if elts
2805	   (set (make-local-variable ',var) elts)
2806	 (kill-local-variable ',var)))))
2807
2808(defun c-set-doc-comment-res ()
2809  ;; Set the variables `c-doc-line-join-re' and
2810  ;; `c-doc-bright-comment-start-re' from the current doc comment style(s).
2811  (c-set-doc-comment-re-element "-line-join-re")
2812  (c-set-doc-comment-re-element "-bright-comment-start-re")
2813  (c-set-doc-comment-char-list "-line-join-end-ch"))
2814
2815(defun c-font-lock-doc-comments (prefix limit keywords)
2816  ;; Fontify the comments between the point and LIMIT whose start
2817  ;; matches PREFIX with `c-doc-face-name'.  Assumes comments have been
2818  ;; fontified with `font-lock-comment-face' already.  nil is always
2819  ;; returned.
2820  ;;
2821  ;; After the fontification of a matching comment, fontification
2822  ;; according to KEYWORDS is applied inside it.  It's a list like
2823  ;; `font-lock-keywords' except that anchored matches and eval
2824  ;; clauses aren't supported and that some abbreviated forms can't be
2825  ;; used.  The buffer is narrowed to the comment while KEYWORDS is
2826  ;; applied; leading comment starters are included but trailing
2827  ;; comment enders for block comment are not.
2828  ;;
2829  ;; Note that faces added through KEYWORDS should never replace the
2830  ;; existing `c-doc-face-name' face since the existence of that face
2831  ;; is used as a flag in other code to skip comments.
2832  ;;
2833  ;; This function might do hidden buffer changes.
2834  (declare (indent 2))
2835  (let (comment-beg region-beg comment-mid)
2836    (if (memq (get-text-property (point) 'face)
2837	      '(font-lock-comment-face font-lock-comment-delimiter-face))
2838	;; Handle the case when the fontified region starts inside a
2839	;; comment.
2840	(let ((start (c-literal-start)))
2841	  (setq region-beg (point)
2842		comment-mid (point))
2843	  (when start
2844	    (goto-char start))
2845	  (when (looking-at prefix)
2846	    (setq comment-beg (point)))))
2847
2848    (while (or
2849	    comment-beg
2850
2851	    ;; Search for the prefix until a match is found at the start
2852	    ;; of a comment.
2853	    (while (when (re-search-forward prefix limit t)
2854		     (setq comment-beg (match-beginning 0))
2855		     (or (not (c-got-face-at comment-beg
2856					     c-literal-faces))
2857			 (and (/= comment-beg (point-min))
2858			      ;; Cheap check which is unreliable (the previous
2859			      ;; character could be the end of a previous
2860			      ;; comment).
2861			      (c-got-face-at (1- comment-beg)
2862					     c-literal-faces)
2863			      ;; Expensive reliable check.
2864			      (save-excursion
2865				(goto-char comment-beg)
2866				(c-in-literal)))))
2867	      (setq comment-beg nil))
2868	    (setq region-beg comment-beg
2869		  comment-mid comment-beg))
2870
2871      (if (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7)
2872	  ;; Collect a sequence of doc style line comments.
2873	  (progn
2874	    (goto-char comment-beg)
2875	    (while (and (progn
2876			  (c-forward-single-comment)
2877			  (c-put-font-lock-face comment-mid (point)
2878						c-doc-face-name)
2879			  (skip-syntax-forward " ")
2880			  (setq comment-beg (point)
2881				comment-mid (point))
2882			  (< (point) limit))
2883			(looking-at prefix))))
2884	(goto-char comment-beg)
2885	(c-forward-single-comment)
2886	(c-put-font-lock-face region-beg (point) c-doc-face-name))
2887      (if (> (point) limit) (goto-char limit))
2888      (setq comment-beg nil)
2889
2890      (let ((region-end (point))
2891	    (keylist keywords) keyword matcher highlights)
2892	(save-restriction
2893	  ;; Narrow to the doc comment.  Among other things, this
2894	  ;; helps by making "^" match at the start of the comment.
2895	  ;; Do not include a trailing block comment ender, though.
2896	  (and (> region-end (1+ region-beg))
2897	       (progn (goto-char region-end)
2898		      (backward-char 2)
2899		      (looking-at "\\*/"))
2900	       (setq region-end (point)))
2901	  (narrow-to-region region-beg region-end)
2902
2903	  (while keylist
2904	    (setq keyword (car keylist)
2905		  keylist (cdr keylist)
2906		  matcher (car keyword))
2907	    (goto-char region-beg)
2908	    (while (if (stringp matcher)
2909		       (re-search-forward matcher region-end t)
2910		     (funcall matcher region-end))
2911	      (setq highlights (cdr keyword))
2912	      (if (consp (car highlights))
2913		  (while highlights
2914		    (font-lock-apply-highlight (car highlights))
2915		    (setq highlights (cdr highlights)))
2916		(font-lock-apply-highlight highlights))))
2917
2918	  (goto-char region-end)))))
2919  nil)
2920
2921(defun c-find-invalid-doc-markup (regexp limit)
2922  ;; Used to fontify invalid markup in doc comments after the correct
2923  ;; ones have been fontified: Find the first occurrence of REGEXP
2924  ;; between the point and LIMIT that only is fontified with
2925  ;; `c-doc-face-name'.  If a match is found then submatch 0 surrounds
2926  ;; the first char and t is returned, otherwise nil is returned.
2927  ;;
2928  ;; This function might do hidden buffer changes.
2929  (let (start)
2930    (while (if (re-search-forward regexp limit t)
2931	       (not (eq (get-text-property
2932			 (setq start (match-beginning 0)) 'face)
2933			c-doc-face-name))
2934	     (setq start nil)))
2935    (when start
2936      (store-match-data (list (copy-marker start)
2937			      (copy-marker (1+ start))))
2938      t)))
2939
2940;; GtkDoc patterns contributed by Masatake YAMATO <yamato@redhat.com>.
2941
2942(defconst gtkdoc-font-lock-doc-comments
2943  (let ((symbol "[a-zA-Z0-9_]+")
2944	(header "^ \\* "))
2945    `((,(concat header "\\("     symbol "\\):[ \t]*$")
2946       1 ,c-doc-markup-face-name prepend nil)
2947      (,(concat                  symbol     "()")
2948       0 ,c-doc-markup-face-name prepend nil)
2949      (,(concat header "\\(" "@" symbol "\\):")
2950       1 ,c-doc-markup-face-name prepend nil)
2951      (,(concat "[#%@]" symbol)
2952       0 ,c-doc-markup-face-name prepend nil))
2953    ))
2954
2955(defconst gtkdoc-font-lock-doc-protection
2956  `(("< \\(public\\|private\\|protected\\) >"
2957     1 ,c-doc-markup-face-name prepend nil)))
2958
2959(defconst gtkdoc-font-lock-keywords
2960  `((,(lambda (limit)
2961	(c-font-lock-doc-comments "/\\*\\*\\([^*/\n\r].*\\)?$" limit
2962	  gtkdoc-font-lock-doc-comments)
2963	(c-font-lock-doc-comments "/\\*< " limit
2964	  gtkdoc-font-lock-doc-protection)
2965	))))
2966
2967;; Javadoc.
2968
2969(defconst javadoc-font-lock-doc-comments
2970  `(("{@[a-z]+[^}\n\r]*}"		; "{@foo ...}" markup.
2971     0 ,c-doc-markup-face-name prepend nil)
2972    ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup.
2973     3 ,c-doc-markup-face-name prepend nil)
2974    (,(concat "</?\\sw"			; HTML tags.
2975	      "\\("
2976	      (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"
2977		      "\"[^\"]*\"\\|'[^']*'")
2978	      "\\)*>")
2979     0 ,c-doc-markup-face-name prepend nil)
2980    ("&\\(\\sw\\|[.:]\\)+;"		; HTML entities.
2981     0 ,c-doc-markup-face-name prepend nil)
2982    ;; Fontify remaining markup characters as invalid.  Note
2983    ;; that the Javadoc spec is hazy about when "@" is
2984    ;; allowed in non-markup use.
2985    (,(lambda (limit)
2986	(c-find-invalid-doc-markup "[<>&]\\|{@" limit))
2987     0 'font-lock-warning-face prepend nil)))
2988
2989(defconst javadoc-font-lock-keywords
2990  `((,(lambda (limit)
2991	(c-font-lock-doc-comments "/\\*\\*" limit
2992	  javadoc-font-lock-doc-comments)))))
2993
2994;; Pike autodoc.
2995
2996(defconst autodoc-decl-keywords
2997  ;; Adorned regexp matching the keywords that introduce declarations
2998  ;; in Pike Autodoc.
2999  (cc-eval-when-compile
3000    (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode)))
3001
3002(defconst autodoc-decl-type-keywords
3003  ;; Adorned regexp matching the keywords that are followed by a type.
3004  (cc-eval-when-compile
3005    (c-make-keywords-re t '("@elem" "@member") 'pike-mode)))
3006
3007(defun autodoc-font-lock-line-markup (limit)
3008  ;; Fontify all line oriented keywords between the point and LIMIT.
3009  ;; Nil is always returned.
3010  ;;
3011  ;; This function might do hidden buffer changes.
3012
3013  (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("
3014			 c-current-comment-prefix
3015			 "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)"))
3016	(markup-faces (list c-doc-markup-face-name c-doc-face-name)))
3017
3018    (while (and (< (point) limit)
3019		(re-search-forward line-re limit t))
3020      (goto-char (match-end 1))
3021
3022      (if (looking-at autodoc-decl-keywords)
3023	  (let* ((kwd-pos (point))
3024		 (start (match-end 1))
3025		 (pos start)
3026		 end)
3027
3028	    (c-put-font-lock-face (point) pos markup-faces)
3029
3030	    ;; Put a declaration end mark at the markup keyword and
3031	    ;; remove the faces from the rest of the line so that it
3032	    ;; gets refontified as a declaration later on by
3033	    ;; `c-font-lock-declarations'.
3034	    (c-put-char-property (1- pos) 'c-type 'c-decl-end)
3035	    (goto-char pos)
3036	    (while (progn
3037		     (end-of-line)
3038		     (setq end (point))
3039		     (and (eq (char-before) ?@)
3040			  (not (eobp))
3041			  (progn (forward-char)
3042				 (skip-syntax-forward " ")
3043				 (looking-at c-current-comment-prefix))))
3044	      (goto-char (match-end 0))
3045	      (c-remove-font-lock-face pos (1- end))
3046	      (c-put-font-lock-face (1- end) end markup-faces)
3047	      (setq pos (point)))
3048
3049	    ;; Include the final newline in the removed area.  This
3050	    ;; has no visual effect but it avoids some tricky special
3051	    ;; cases in the testsuite wrt the differences in string
3052	    ;; fontification in Emacs vs XEmacs.
3053	    (c-remove-font-lock-face pos (min (1+ (point)) (point-max)))
3054
3055	    ;; Must handle string literals explicitly inside the declaration.
3056	    (goto-char start)
3057	    (while (re-search-forward
3058		    "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'"
3059		    end 'move)
3060	      (c-put-font-lock-string-face (match-beginning 0)
3061					   (point)))
3062
3063	    ;; Fontify types after keywords that always are followed
3064	    ;; by them.
3065	    (goto-char kwd-pos)
3066	    (when (looking-at autodoc-decl-type-keywords)
3067	      (c-fontify-types-and-refs ((c-promote-possible-types t))
3068		(goto-char start)
3069		(c-forward-syntactic-ws)
3070		(c-forward-type))))
3071
3072	;; Mark each whole line as markup, as long as the logical line
3073	;; continues.
3074	(while (progn
3075		 (c-put-font-lock-face (point)
3076				       (progn (end-of-line) (point))
3077				       markup-faces)
3078		 (and (eq (char-before) ?@)
3079		      (not (eobp))
3080		      (progn (forward-char)
3081			     (skip-syntax-forward " ")
3082			     (looking-at c-current-comment-prefix))))
3083	  (goto-char (match-end 0))))))
3084
3085  nil)
3086
3087(defconst autodoc-font-lock-doc-comments
3088  `(("@\\(\\w+{\\|\\[\\([^]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)"
3089     ;; In-text markup.
3090     0 ,c-doc-markup-face-name prepend nil)
3091    (autodoc-font-lock-line-markup)
3092    ;; Fontify remaining markup characters as invalid.
3093    (,(lambda (limit)
3094	(c-find-invalid-doc-markup "@" limit))
3095     0 'font-lock-warning-face prepend nil)
3096    ))
3097
3098(defconst autodoc-line-join-re "@[\n\r][ \t]*/[/*]!")
3099;; Matches a line continuation in autodoc comment style.
3100(defconst autodoc-bright-comment-start-re "/[/*]!")
3101;; Matches an autodoc comment opener.
3102(defconst autodoc-line-join-end-ch ?!)
3103;; The final character of `autodoc-line-join-re'.
3104
3105(defun autodoc-font-lock-keywords ()
3106  ;; Note that we depend on that `c-current-comment-prefix' has got
3107  ;; its proper value here.
3108  ;;
3109  ;; This function might do hidden buffer changes.
3110
3111  ;; The `c-type' text property with `c-decl-end' is used to mark the
3112  ;; end of the `autodoc-decl-keywords' occurrences to fontify the
3113  ;; following declarations.
3114  (setq c-type-decl-end-used t)
3115
3116  `((,(lambda (limit)
3117	(c-font-lock-doc-comments "/[*/]!" limit
3118	  autodoc-font-lock-doc-comments)))))
3119
3120;; Doxygen
3121
3122(defconst doxygen-font-lock-doc-comments
3123  ;; TODO: Handle @code, @verbatim, @dot, @f etc. better by not highlighting
3124  ;; text inside of those commands.  Something smarter than just regexes may be
3125  ;; needed to do that efficiently.
3126  `((,(concat
3127       ;; Make sure that the special character has not been escaped.  E.g. in
3128       ;; `\@foo' only `\@' is a command (similarly for other characters like
3129       ;; `\\foo', `\<foo' and `\&foo').  The downside now is that we don't
3130       ;; match command started just after an escaped character, e.g. in
3131       ;; `\@\foo' we should match `\@' as well as `\foo' but only the former
3132       ;; is matched.
3133       "\\(?:^\\|[^\\@]\\)\\("
3134         ;; Doxygen commands start with backslash or an at sign.  Note that for
3135         ;; brevity in the comments only `\' will be mentioned.
3136         "[\\@]\\(?:"
3137           ;; Doxygen commands except those starting with `f'
3138           "[a-eg-z][a-z]*"
3139           ;; Doxygen command starting with `f':
3140           "\\|f\\(?:"
3141             "[][$}]"                         ; \f$ \f} \f[ \f]
3142             "\\|{\\(?:[a-zA-Z]+\\*?}{?\\)?"  ; \f{ \f{env} \f{env}{
3143             "\\|[a-z]+"                      ; \foo
3144           "\\)"
3145           "\\|~[a-zA-Z]*"             ; \~  \~language
3146           "\\|[$@&~<=>#%\".|\\\\]"    ; single-character escapes
3147           "\\|::\\|---?"              ; \:: \-- \---
3148         "\\)"
3149         ;; HTML tags and entities:
3150         "\\|</?\\sw\\(?:\\sw\\|\\s \\|[=\n\r*.:]\\|\"[^\"]*\"\\|'[^']*'\\)*>"
3151         "\\|&\\(?:\\sw+\\|#[0-9]+\\|#x[0-9a-fA-F]+\\);"
3152       "\\)")
3153     1 ,c-doc-markup-face-name prepend nil)
3154    ;; Commands inside of strings are not commands so override highlighting with
3155    ;; string face.  This also affects HTML attribute values if they are
3156    ;; surrounded with double quotes which may or may not be considered a good
3157    ;; thing.
3158    ("\\(?:^\\|[^\\@]\\)\\(\"[^\"[:cntrl:]]+\"\\)"
3159     1 font-lock-string-face prepend nil)
3160    ;; HTML comments inside of the Doxygen comments.
3161    ("\\(?:^\\|[^\\@]\\)\\(<!--.*?-->\\)"
3162     1 font-lock-comment-face prepend nil)
3163    ;; Autolinking. Doxygen auto-links anything that is a class name but we have
3164    ;; no hope of matching those.  We are, however, able to match functions and
3165    ;; members using explicit scoped syntax.  For functions, we can also find
3166    ;; them by noticing argument-list.  Note that Doxygen accepts `::' as well
3167    ;; as `#' as scope operators.
3168    (,(let* ((ref "[\\@]ref\\s-+")
3169             (ref-opt (concat "\\(?:" ref "\\)?"))
3170             (id "[a-zA-Z_][a-zA-Z_0-9]*")
3171             (args "\\(?:()\\|([^()]*)\\)")
3172             (scope "\\(?:#\\|::\\)"))
3173        (concat
3174         "\\(?:^\\|[^\\@/%:]\\)\\(?:"
3175                 ref-opt "\\(?1:" scope "?" "\\(?:" id scope "\\)+" "~?" id "\\)"
3176           "\\|" ref-opt "\\(?1:" scope     "~?" id "\\)"
3177           "\\|" ref-opt "\\(?1:" scope "?" "~?" id "\\)" args
3178           "\\|" ref     "\\(?1:" "~?" id "\\)"
3179           "\\|" ref-opt "\\(?1:~[A-Z][a-zA-Z0-9_]+\\)"
3180         "\\)"))
3181     1 font-lock-function-name-face prepend nil)
3182    ;; Match URLs and emails.  This has two purposes.  First of all, Doxygen
3183    ;; autolinks URLs.  Second of all, `@bar' in `foo@bar.baz' has been matched
3184    ;; above as a command; try and overwrite it.
3185    (,(let* ((host "[A-Za-z0-9]\\(?:[A-Za-z0-9-]\\{0,61\\}[A-Za-z0-9]\\)")
3186             (fqdn (concat "\\(?:" host "\\.\\)+" host))
3187             (comp "[!-(*--/-=?-~]+")
3188             (path (concat "/\\(?:" comp "[.]+" "\\)*" comp)))
3189        (concat "\\(?:mailto:\\)?[a-zA-0_.]+@" fqdn
3190                "\\|https?://" fqdn "\\(?:" path "\\)?"))
3191     0 font-lock-keyword-face prepend nil)))
3192
3193(defconst doxygen-font-lock-keywords
3194  `((,(lambda (limit)
3195        (c-font-lock-doc-comments "/\\(?:/[/!]\\|\\*[\\*!]\\)"
3196            limit doxygen-font-lock-doc-comments)))))
3197
3198
3199;; 2006-07-10:  awk-font-lock-keywords has been moved back to cc-awk.el.
3200(cc-provide 'cc-fonts)
3201
3202;; Local Variables:
3203;; indent-tabs-mode: t
3204;; tab-width: 8
3205;; End:
3206;;; cc-fonts.el ends here
3207