1;;; cc-fonts.el --- font lock support for CC Mode
2
3;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 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;; Version:    See cc-mode.el
10;; Keywords:   c languages oop
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 2, or (at your option)
17;; 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 this program; see the file COPYING.  If not, write to
26;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA.
28
29;;; Commentary:
30
31;; Some comments on the use of faces:
32;;
33;; o  `c-label-face-name' is either `font-lock-constant-face' (in
34;;    Emacs), or `font-lock-reference-face'.
35;;
36;; o  `c-constant-face-name', `c-reference-face-name' and
37;;    `c-doc-markup-face-name' are essentially set up like
38;;    `c-label-face-name'.
39;;
40;; o  `c-preprocessor-face-name' is `font-lock-preprocessor-face' in
41;;    XEmacs and - in lack of a closer equivalent -
42;;    `font-lock-builtin-face' or `font-lock-reference-face' in Emacs.
43;;
44;; o  `c-doc-face-name' is `font-lock-doc-string-face' in XEmacs,
45;;    `font-lock-doc-face' in Emacs 21 and later, or
46;;    `font-lock-comment-face' in older Emacs (that since source
47;;    documentation are actually comments in these languages, as opposed
48;;    to elisp).
49;;
50;; TBD: We should probably provide real faces for the above uses and
51;; instead initialize them from the standard faces.
52
53;;; Code:
54
55;; The faces that already have been put onto the text is tested in
56;; various places to direct further fontifications.  For this to work,
57;; the following assumptions regarding the faces must hold (apart from
58;; the dependencies on the font locking order):
59;;
60;; o  `font-lock-comment-face' and the face in `c-doc-face-name' is
61;;    not used in anything but comments.
62;; o  If any face (e.g. `c-doc-markup-face-name') but those above is
63;;    used in comments, it doesn't replace them.
64;; o  `font-lock-string-face' is not used in anything but string
65;;    literals (single or double quoted).
66;; o  `font-lock-keyword-face' and the face in `c-label-face-name' are
67;;    never overlaid with other faces.
68
69(eval-when-compile
70  (let ((load-path
71	 (if (and (boundp 'byte-compile-dest-file)
72		  (stringp byte-compile-dest-file))
73	     (cons (file-name-directory byte-compile-dest-file) load-path)
74	   load-path)))
75    (load "cc-bytecomp" nil t)))
76
77(cc-require 'cc-defs)
78(cc-require-when-compile 'cc-langs)
79(cc-require 'cc-vars)
80(cc-require 'cc-engine)
81(cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to
82;; prevent cc-awk being loaded when it's not needed.  There is now a (require
83;; 'cc-awk) in (defun awk-mode ..).
84
85;; Avoid repeated loading through the eval-after-load directive in
86;; cc-mode.el.
87(provide 'cc-fonts)
88
89(cc-external-require 'font-lock)
90
91(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only.
92
93;; Need to declare these local symbols during compilation since
94;; they're referenced from lambdas in `byte-compile' calls that are
95;; executed at compile time.  They don't need to have the proper
96;; definitions, though, since the generated functions aren't called
97;; during compilation.
98(cc-bytecomp-defvar c-preprocessor-face-name)
99(cc-bytecomp-defvar c-reference-face-name)
100(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
101(cc-bytecomp-defun c-font-lock-declarators)
102(cc-bytecomp-defun c-font-lock-objc-method)
103(cc-bytecomp-defun c-font-lock-invalid-string)
104
105
106;; Note that font-lock in XEmacs doesn't expand face names as
107;; variables, so we have to use the (eval . FORM) in the font lock
108;; matchers wherever we use these alias variables.
109
110(defconst c-preprocessor-face-name
111  (cond ((c-face-name-p 'font-lock-preprocessor-face)
112	 ;; XEmacs has a font-lock-preprocessor-face.
113	 'font-lock-preprocessor-face)
114	((c-face-name-p 'font-lock-builtin-face)
115	 ;; In Emacs font-lock-builtin-face has traditionally been
116	 ;; used for preprocessor directives.
117	 'font-lock-builtin-face)
118	(t
119	 'font-lock-reference-face)))
120
121(cc-bytecomp-defvar font-lock-constant-face)
122
123(defconst c-label-face-name
124  (cond ((c-face-name-p 'font-lock-label-face)
125	 ;; If it happens to occur in the future.  (Well, the more
126	 ;; pragmatic reason is to get unique faces for the test
127	 ;; suite.)
128	 'font-lock-label-face)
129	((and (c-face-name-p 'font-lock-constant-face)
130	      (eq font-lock-constant-face 'font-lock-constant-face))
131	 ;; Test both if font-lock-constant-face exists and that it's
132	 ;; not an alias for something else.  This is important since
133	 ;; we compare already set faces in various places.
134	 'font-lock-constant-face)
135	(t
136	 'font-lock-reference-face)))
137
138(defconst c-constant-face-name
139  (if (and (c-face-name-p 'font-lock-constant-face)
140	   (eq font-lock-constant-face 'font-lock-constant-face))
141      ;; This doesn't exist in some earlier versions of XEmacs 21.
142      'font-lock-constant-face
143    c-label-face-name))
144
145(defconst c-reference-face-name
146  (with-no-warnings
147   (if (and (c-face-name-p 'font-lock-reference-face)
148	    (eq font-lock-reference-face 'font-lock-reference-face))
149       ;; This is considered obsolete in Emacs, but it still maps well
150       ;; to this use.  (Another reason to do this is to get unique
151       ;; faces for the test suite.)
152       'font-lock-reference-face
153     c-label-face-name)))
154
155;; This should not mapped to a face that also is used to fontify things
156;; that aren't comments or string literals.
157(defconst c-doc-face-name
158  (cond ((c-face-name-p 'font-lock-doc-string-face)
159	 ;; XEmacs.
160	 'font-lock-doc-string-face)
161	((c-face-name-p 'font-lock-doc-face)
162	 ;; Emacs 21 and later.
163	 'font-lock-doc-face)
164	(t
165	 'font-lock-comment-face)))
166
167(defconst c-doc-markup-face-name
168  (if (c-face-name-p 'font-lock-doc-markup-face)
169	 ;; If it happens to occur in the future.  (Well, the more
170	 ;; pragmatic reason is to get unique faces for the test
171	 ;; suite.)
172	 'font-lock-doc-markup-face
173    c-label-face-name))
174
175(defconst c-negation-char-face-name
176  (if (c-face-name-p 'font-lock-negation-char-face)
177      ;; Emacs 22 has a special face for negation chars.
178      'font-lock-negation-char-face))
179
180(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
181(cc-bytecomp-defun face-property-instance) ; Only in XEmacs.
182
183(defun c-make-inverse-face (oldface newface)
184  ;; Emacs and XEmacs have completely different face manipulation
185  ;; routines. :P
186  (copy-face oldface newface)
187  (cond ((fboundp 'face-inverse-video-p)
188	 ;; Emacs.  This only looks at the inverse flag in the current
189	 ;; frame.  Other display configurations might be different,
190	 ;; but it can only show if the same Emacs has frames on
191	 ;; e.g. a color and a monochrome display simultaneously.
192	 (unless (face-inverse-video-p oldface)
193	   (invert-face newface)))
194	((fboundp 'face-property-instance)
195	 ;; XEmacs.  Same pitfall here.
196	 (unless (face-property-instance oldface 'reverse)
197	   (invert-face newface)))))
198
199(eval-and-compile
200  ;; We need the following functions during compilation since they're
201  ;; called when the `c-lang-defconst' initializers are evaluated.
202  ;; Define them at runtime too for the sake of derived modes.
203
204  (defmacro c-put-font-lock-face (from to face)
205    ;; Put a face on a region (overriding any existing face) in the way
206    ;; font-lock would do it.  In XEmacs that means putting an
207    ;; additional font-lock property, or else the font-lock package
208    ;; won't recognize it as fontified and might override it
209    ;; incorrectly.
210    ;;
211    ;; This function does a hidden buffer change.
212    (if (fboundp 'font-lock-set-face)
213	;; Note: This function has no docstring in XEmacs so it might be
214	;; considered internal.
215	`(font-lock-set-face ,from ,to ,face)
216      `(put-text-property ,from ,to 'face ,face)))
217
218  (defmacro c-remove-font-lock-face (from to)
219    ;; This is the inverse of `c-put-font-lock-face'.
220    ;;
221    ;; This function does a hidden buffer change.
222    (if (fboundp 'font-lock-remove-face)
223	`(font-lock-remove-face ,from ,to)
224      `(remove-text-properties ,from ,to '(face nil))))
225
226  (defmacro c-put-font-lock-string-face (from to)
227    ;; Put `font-lock-string-face' on a string.  The surrounding
228    ;; quotes are included in Emacs but not in XEmacs.  The passed
229    ;; region should include them.
230    ;;
231    ;; This function does a hidden buffer change.
232    (if (featurep 'xemacs)
233	`(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
234      `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
235
236  (defmacro c-fontify-types-and-refs (varlist &rest body)
237    ;; Like `let', but additionally activates `c-record-type-identifiers'
238    ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
239    ;; accordingly on exit.
240    ;;
241    ;; This function does hidden buffer changes.
242    `(let ((c-record-type-identifiers t)
243	   c-record-ref-identifiers
244	   ,@varlist)
245       (prog1 (progn ,@body)
246	 (c-fontify-recorded-types-and-refs))))
247  (put 'c-fontify-types-and-refs 'lisp-indent-function 1)
248
249  (defun c-skip-comments-and-strings (limit)
250    ;; If the point is within a region fontified as a comment or
251    ;; string literal skip to the end of it or to LIMIT, whichever
252    ;; comes first, and return t.  Otherwise return nil.  The match
253    ;; data is not clobbered.
254    ;;
255    ;; This function might do hidden buffer changes.
256    (when (c-got-face-at (point) c-literal-faces)
257      (while (progn
258	       (goto-char (next-single-property-change
259			   (point) 'face nil limit))
260	       (and (< (point) limit)
261		    (c-got-face-at (point) c-literal-faces))))
262      t))
263
264  (defun c-make-syntactic-matcher (regexp)
265    ;; Returns a byte compiled function suitable for use in place of a
266    ;; regexp string in a `font-lock-keywords' matcher, except that
267    ;; only matches outside comments and string literals count.
268    ;;
269    ;; This function does not do any hidden buffer changes, but the
270    ;; generated functions will.  (They are however used in places
271    ;; covered by the font-lock context.)
272    (byte-compile
273     `(lambda (limit)
274	(let (res)
275	  (while (and (setq res (re-search-forward ,regexp limit t))
276		      (progn
277			(goto-char (match-beginning 0))
278			(or (c-skip-comments-and-strings limit)
279			    (progn
280			      (goto-char (match-end 0))
281			      nil)))))
282	  res))))
283
284  (defun c-make-font-lock-search-function (regexp &rest highlights)
285    ;; This function makes a byte compiled function that works much like
286    ;; a matcher element in `font-lock-keywords'.  It cuts out a little
287    ;; bit of the overhead compared to a real matcher.  The main reason
288    ;; is however to pass the real search limit to the anchored
289    ;; matcher(s), since most (if not all) font-lock implementations
290    ;; arbitrarily limits anchored matchers to the same line, and also
291    ;; to insulate against various other irritating differences between
292    ;; the different (X)Emacs font-lock packages.
293    ;;
294    ;; REGEXP is the matcher, which must be a regexp.  Only matches
295    ;; where the beginning is outside any comment or string literal are
296    ;; significant.
297    ;;
298    ;; HIGHLIGHTS is a list of highlight specs, just like in
299    ;; `font-lock-keywords', with these limitations: The face is always
300    ;; overridden (no big disadvantage, since hits in comments etc are
301    ;; filtered anyway), there is no "laxmatch", and an anchored matcher
302    ;; is always a form which must do all the fontification directly.
303    ;; `limit' is a variable bound to the real limit in the context of
304    ;; the anchored matcher forms.
305    ;;
306    ;; This function does not do any hidden buffer changes, but the
307    ;; generated functions will.  (They are however used in places
308    ;; covered by the font-lock context.)
309
310    ;; Note: Replace `byte-compile' with `eval' to debug the generated
311    ;; lambda easier.
312    (byte-compile
313     `(lambda (limit)
314	(let (;; The font-lock package in Emacs is known to clobber
315	      ;; `parse-sexp-lookup-properties' (when it exists).
316	      (parse-sexp-lookup-properties
317	       (cc-eval-when-compile
318		 (boundp 'parse-sexp-lookup-properties))))
319	  (while (re-search-forward ,regexp limit t)
320	    (unless (progn
321		      (goto-char (match-beginning 0))
322		      (c-skip-comments-and-strings limit))
323	      (goto-char (match-end 0))
324	      ,@(mapcar
325		 (lambda (highlight)
326		   (if (integerp (car highlight))
327		       (progn
328			 (unless (eq (nth 2 highlight) t)
329			   (error
330			    "The override flag must currently be t in %s"
331			    highlight))
332			 (when (nth 3 highlight)
333			   (error
334			    "The laxmatch flag may currently not be set in %s"
335			    highlight))
336			 `(save-match-data
337			    (c-put-font-lock-face
338			     (match-beginning ,(car highlight))
339			     (match-end ,(car highlight))
340			     ,(elt highlight 1))))
341		     (when (nth 3 highlight)
342		       (error "Match highlights currently not supported in %s"
343			      highlight))
344		     `(progn
345			,(nth 1 highlight)
346			(save-match-data ,(car highlight))
347			,(nth 2 highlight))))
348		 highlights))))
349	nil)))
350
351;  (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
352;    '(progn
353  (def-edebug-spec c-fontify-types-and-refs let*)
354  (def-edebug-spec c-make-syntactic-matcher t)
355  ;; If there are literal quoted or backquoted highlight specs in
356  ;; the call to `c-make-font-lock-search-function' then let's
357  ;; instrument the forms in them.
358  (def-edebug-spec c-make-font-lock-search-function
359    (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)));))
360
361(defun c-fontify-recorded-types-and-refs ()
362  ;; Convert the ranges recorded on `c-record-type-identifiers' and
363  ;; `c-record-ref-identifiers' to fontification.
364  ;;
365  ;; This function does hidden buffer changes.
366  (let (elem)
367    (while (consp c-record-type-identifiers)
368      (setq elem (car c-record-type-identifiers)
369	    c-record-type-identifiers (cdr c-record-type-identifiers))
370      (c-put-font-lock-face (car elem) (cdr elem)
371			    'font-lock-type-face))
372    (while c-record-ref-identifiers
373      (setq elem (car c-record-ref-identifiers)
374	    c-record-ref-identifiers (cdr c-record-ref-identifiers))
375      ;; Note that the reference face is a variable that is
376      ;; dereferenced, since it's an alias in Emacs.
377      (c-put-font-lock-face (car elem) (cdr elem)
378			    c-reference-face-name))))
379
380(c-lang-defconst c-cpp-matchers
381  "Font lock matchers for preprocessor directives and purely lexical
382stuff.  Used on level 1 and higher."
383
384  ;; Note: `c-font-lock-declarations' assumes that no matcher here
385  ;; sets `font-lock-type-face' in languages where
386  ;; `c-recognize-<>-arglists' is set.
387
388  t `(,@(when (c-lang-const c-opt-cpp-prefix)
389	  (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
390		 (ncle-depth (regexp-opt-depth noncontinued-line-end))
391		 (sws-depth (c-lang-const c-syntactic-ws-depth))
392		 (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
393
394	    `(;; The stuff after #error and #warning is a message, so
395	      ;; fontify it as a string.
396	      ,@(when (c-lang-const c-cpp-message-directives)
397		  (let* ((re (c-make-keywords-re nil
398			       (c-lang-const c-cpp-message-directives)))
399			 (re-depth (regexp-opt-depth re)))
400		    `((,(concat noncontinued-line-end
401				(c-lang-const c-opt-cpp-prefix)
402				re
403				"\\s +\\(.*\\)$")
404		       ,(+ ncle-depth re-depth 1) font-lock-string-face))))
405
406	      ;; Fontify filenames in #include <...> as strings.
407	      ,@(when (c-lang-const c-cpp-include-directives)
408		  (let* ((re (c-make-keywords-re nil
409			       (c-lang-const c-cpp-include-directives)))
410			 (re-depth (regexp-opt-depth re)))
411		    `((,(concat noncontinued-line-end
412				(c-lang-const c-opt-cpp-prefix)
413				re
414				(c-lang-const c-syntactic-ws)
415				"\\(<[^>\n\r]*>?\\)")
416		       (,(+ ncle-depth re-depth sws-depth 1)
417			font-lock-string-face)
418
419		       ;; Use an anchored matcher to put paren syntax
420		       ;; on the brackets.
421		       (,(byte-compile
422			  `(lambda (limit)
423			     (let ((beg (match-beginning
424					 ,(+ ncle-depth re-depth sws-depth 1)))
425				   (end (1- (match-end ,(+ ncle-depth re-depth
426							   sws-depth 1)))))
427			       (if (eq (char-after end) ?>)
428				   (progn
429				     (c-mark-<-as-paren beg)
430				     (c-mark->-as-paren end))
431				 (c-clear-char-property beg 'syntax-table)))
432			     nil)))))))
433
434	      ;; #define.
435	      ,@(when (c-lang-const c-opt-cpp-macro-define)
436		  `((,(c-make-font-lock-search-function
437		       (concat
438			noncontinued-line-end
439			(c-lang-const c-opt-cpp-prefix)
440			(c-lang-const c-opt-cpp-macro-define)
441			(c-lang-const c-nonempty-syntactic-ws)
442			"\\(" (c-lang-const ; 1 + ncle + nsws
443			       c-symbol-key) "\\)"
444			(concat "\\("	; 2 + ncle + nsws + c-sym-key
445				;; Macro with arguments - a "function".
446				"\\(\(\\)" ; 3 + ncle + nsws + c-sym-key
447				"\\|"
448				;; Macro without arguments - a "variable".
449				"\\([^\(]\\|$\\)"
450				"\\)"))
451		       `((if (match-beginning
452			      ,(+ 3 ncle-depth nsws-depth
453				  (c-lang-const c-symbol-key-depth)))
454
455			     ;; "Function".  Fontify the name and the arguments.
456			     (save-restriction
457			       (c-put-font-lock-face
458				(match-beginning ,(+ 1 ncle-depth nsws-depth))
459				(match-end ,(+ 1 ncle-depth nsws-depth))
460				'font-lock-function-name-face)
461			       (goto-char
462				(match-end
463				 ,(+ 3 ncle-depth nsws-depth
464				     (c-lang-const c-symbol-key-depth))))
465
466			       (narrow-to-region (point-min) limit)
467			       (while (and
468				       (progn
469					 (c-forward-syntactic-ws)
470					 (looking-at c-symbol-key))
471				       (progn
472					 (c-put-font-lock-face
473					  (match-beginning 0) (match-end 0)
474					  'font-lock-variable-name-face)
475					 (goto-char (match-end 0))
476					 (c-forward-syntactic-ws)
477					 (eq (char-after) ?,)))
478				 (forward-char)))
479
480			   ;; "Variable".
481			   (c-put-font-lock-face
482			    (match-beginning ,(+ 1 ncle-depth nsws-depth))
483			    (match-end ,(+ 1 ncle-depth nsws-depth))
484			    'font-lock-variable-name-face)))))))
485
486	      ;; Fontify cpp function names in preprocessor
487	      ;; expressions in #if and #elif.
488	      ,@(when (and (c-lang-const c-cpp-expr-directives)
489			   (c-lang-const c-cpp-expr-functions))
490		  (let ((ced-re (c-make-keywords-re t
491				  (c-lang-const c-cpp-expr-directives)))
492			(cef-re (c-make-keywords-re t
493				  (c-lang-const c-cpp-expr-functions))))
494		    `((,(c-make-font-lock-search-function
495			 (concat noncontinued-line-end
496				 (c-lang-const c-opt-cpp-prefix)
497				 ced-re ; 1 + ncle-depth
498				 ;; Match the whole logical line to look
499				 ;; for the functions in.
500				 "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")
501			 `((let ((limit (match-end 0)))
502			     (while (re-search-forward ,cef-re limit 'move)
503			       (c-put-font-lock-face (match-beginning 1)
504						     (match-end 1)
505						     c-preprocessor-face-name)))
506			   (goto-char (match-end ,(1+ ncle-depth)))))))))
507
508	      ;; Fontify the directive names.
509	      (,(c-make-font-lock-search-function
510		 (concat noncontinued-line-end
511			 "\\("
512			 (c-lang-const c-opt-cpp-prefix)
513			 "[" (c-lang-const c-symbol-chars) "]+"
514			 "\\)")
515		 `(,(1+ ncle-depth) c-preprocessor-face-name t)))
516
517	      (eval . (list ,(c-make-syntactic-matcher
518			      (concat noncontinued-line-end
519				      (c-lang-const c-opt-cpp-prefix)
520				      "if\\(n\\)def\\>"))
521			    ,(+ ncle-depth 1)
522			    c-negation-char-face-name
523			    'append))
524	      )))
525
526      ,@(when (c-major-mode-is 'pike-mode)
527	  ;; Recognize hashbangs in Pike.
528	  `((eval . (list "\\`#![^\n\r]*"
529			  0 c-preprocessor-face-name))))
530
531      ;; Make hard spaces visible through an inverted `font-lock-warning-face'.
532      (eval . (list
533	       "\240"
534	       0 (progn
535		   (unless (c-face-name-p 'c-nonbreakable-space-face)
536		     (c-make-inverse-face 'font-lock-warning-face
537					  'c-nonbreakable-space-face))
538		   ''c-nonbreakable-space-face)))
539      ))
540
541(defun c-font-lock-invalid-string ()
542  ;; Assuming the point is after the opening character of a string,
543  ;; fontify that char with `font-lock-warning-face' if the string
544  ;; decidedly isn't terminated properly.
545  ;;
546  ;; This function does hidden buffer changes.
547  (let ((start (1- (point))))
548    (save-excursion
549      (and (eq (elt (parse-partial-sexp start (c-point 'eol)) 8) start)
550	   (if (integerp c-multiline-string-start-char)
551	       ;; There's no multiline string start char before the
552	       ;; string, so newlines aren't allowed.
553	       (not (eq (char-before start) c-multiline-string-start-char))
554	     ;; Multiline strings are allowed anywhere if
555	     ;; c-multiline-string-start-char is t.
556	     (not c-multiline-string-start-char))
557	   (if c-string-escaped-newlines
558	       ;; There's no \ before the newline.
559	       (not (eq (char-before (point)) ?\\))
560	     ;; Escaped newlines aren't supported.
561	     t)
562	   (c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
563
564(c-lang-defconst c-basic-matchers-before
565  "Font lock matchers for basic keywords, labels, references and various
566other easily recognizable things that should be fontified before generic
567casts and declarations are fontified.  Used on level 2 and higher."
568
569  ;; Note: `c-font-lock-declarations' assumes that no matcher here
570  ;; sets `font-lock-type-face' in languages where
571  ;; `c-recognize-<>-arglists' is set.
572
573  t `(;; Put a warning face on the opener of unclosed strings that
574      ;; can't span lines.  Later font
575      ;; lock packages have a `font-lock-syntactic-face-function' for
576      ;; this, but it doesn't give the control we want since any
577      ;; fontification done inside the function will be
578      ;; unconditionally overridden.
579      ,(c-make-font-lock-search-function
580	;; Match a char before the string starter to make
581	;; `c-skip-comments-and-strings' work correctly.
582	(concat ".\\(" c-string-limit-regexp "\\)")
583	'((c-font-lock-invalid-string)))
584
585      ;; Fontify keyword constants.
586      ,@(when (c-lang-const c-constant-kwds)
587	  (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
588	    (if (c-major-mode-is 'pike-mode)
589		;; No symbol is a keyword after "->" in Pike.
590		`((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
591					 "\\<\\(" re "\\)\\>")
592				2 c-constant-face-name)))
593	      `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
594			      1 c-constant-face-name))))))
595
596      ;; Fontify all keywords except the primitive types.
597      ,(if (c-major-mode-is 'pike-mode)
598	   ;; No symbol is a keyword after "->" in Pike.
599	   `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
600		      "\\<" (c-lang-const c-regular-keywords-regexp))
601	     2 font-lock-keyword-face)
602	 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
603	   1 font-lock-keyword-face))
604
605      ;; Fontify leading identifiers in fully qualified names like
606      ;; "foo::bar" in languages that supports such things.
607      ,@(when (c-lang-const c-opt-identifier-concat-key)
608	  (if (c-major-mode-is 'java-mode)
609	      ;; Java needs special treatment since "." is used both to
610	      ;; qualify names and in normal indexing.  Here we look for
611	      ;; capital characters at the beginning of an identifier to
612	      ;; recognize the class.  "*" is also recognized to cover
613	      ;; wildcard import declarations.  All preceding dot separated
614	      ;; identifiers are taken as package names and therefore
615	      ;; fontified as references.
616	      `(,(c-make-font-lock-search-function
617		  ;; Search for class identifiers preceded by ".".  The
618		  ;; anchored matcher takes it from there.
619		  (concat (c-lang-const c-opt-identifier-concat-key)
620			  (c-lang-const c-simple-ws) "*"
621			  (concat "\\("
622				  "[" c-upper "]"
623				  "[" (c-lang-const c-symbol-chars) "]*"
624				  "\\|"
625				  "\\*"
626				  "\\)"))
627		  `((let (id-end)
628		      (goto-char (1+ (match-beginning 0)))
629		      (while (and (eq (char-before) ?.)
630				  (progn
631				    (backward-char)
632				    (c-backward-syntactic-ws)
633				    (setq id-end (point))
634				    (< (skip-chars-backward
635					,(c-lang-const c-symbol-chars)) 0))
636				  (not (get-text-property (point) 'face)))
637			(c-put-font-lock-face (point) id-end
638					      c-reference-face-name)
639			(c-backward-syntactic-ws)))
640		    nil
641		    (goto-char (match-end 0)))))
642
643	    `((,(byte-compile
644		 ;; Must use a function here since we match longer than
645		 ;; we want to move before doing a new search.  This is
646		 ;; not necessary for XEmacs since it restarts the
647		 ;; search from the end of the first highlighted
648		 ;; submatch (something that causes problems in other
649		 ;; places).
650		 `(lambda (limit)
651		    (while (re-search-forward
652			    ,(concat "\\(\\<" ; 1
653				     "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
654				     (c-lang-const c-simple-ws) "*"
655				     (c-lang-const c-opt-identifier-concat-key)
656				     (c-lang-const c-simple-ws) "*"
657				     "\\)"
658				     "\\("
659				     (c-lang-const c-opt-after-id-concat-key)
660				     "\\)")
661			    limit t)
662		      (unless (progn
663				(goto-char (match-beginning 0))
664				(c-skip-comments-and-strings limit))
665			(or (get-text-property (match-beginning 2) 'face)
666			    (c-put-font-lock-face (match-beginning 2)
667						  (match-end 2)
668						  c-reference-face-name))
669			(goto-char (match-end 1))))))))))
670
671      ;; Fontify the special declarations in Objective-C.
672      ,@(when (c-major-mode-is 'objc-mode)
673	  `(;; Fontify class names in the beginning of message expressions.
674	    ,(c-make-font-lock-search-function
675	      "\\["
676	      '((c-fontify-types-and-refs ()
677		  (c-forward-syntactic-ws limit)
678		  (let ((start (point)))
679		    ;; In this case we accept both primitive and known types.
680		    (when (eq (c-forward-type) 'known)
681		      (goto-char start)
682		      (let ((c-promote-possible-types t))
683			(c-forward-type))))
684		  (if (> (point) limit) (goto-char limit)))))
685
686	    ;; The @interface/@implementation/@protocol directives.
687	    ,(c-make-font-lock-search-function
688	      (concat "\\<"
689		      (regexp-opt
690		       '("@interface" "@implementation" "@protocol")
691		       t)
692		      "\\>")
693	      '((c-fontify-types-and-refs
694		    (;; The font-lock package in Emacs is known to clobber
695		     ;; `parse-sexp-lookup-properties' (when it exists).
696		     (parse-sexp-lookup-properties
697		      (cc-eval-when-compile
698			(boundp 'parse-sexp-lookup-properties))))
699		  (c-forward-objc-directive)
700		  nil)
701		(goto-char (match-beginning 0))))))
702
703      (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name))
704      ))
705
706(defun c-font-lock-complex-decl-prepare (limit)
707  ;; This function will be called from font-lock for a region bounded by POINT
708  ;; and LIMIT, as though it were to identify a keyword for
709  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
710  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
711  ;; Fontification".
712  ;;
713  ;; Called before any of the matchers in `c-complex-decl-matchers'.
714  ;;
715  ;; This function does hidden buffer changes.
716
717  ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
718
719  ;; Clear the list of found types if we start from the start of the
720  ;; buffer, to make it easier to get rid of misspelled types and
721  ;; variables that has gotten recognized as types in malformed code.
722  (when (bobp)
723    (c-clear-found-types))
724
725  ;; Clear the c-type char properties in the region to recalculate
726  ;; them properly. This is necessary e.g. to handle constructs that
727  ;; might been required as declarations temporarily during editing.
728  ;; The interesting properties are anyway those put on the closest
729  ;; token before the region.
730  (c-clear-char-properties (point) limit 'c-type)
731
732  ;; Update `c-state-cache' to the beginning of the region.  This will
733  ;; make `c-beginning-of-syntax' go faster when it's used later on,
734  ;; and it's near the point most of the time.
735  (c-parse-state)
736
737  ;; Check if the fontified region starts inside a declarator list so
738  ;; that `c-font-lock-declarators' should be called at the start.
739  (let ((prop (save-excursion
740		(c-backward-syntactic-ws)
741		(unless (bobp)
742		  (c-get-char-property (1- (point)) 'c-type)))))
743    (when (memq prop '(c-decl-id-start c-decl-type-start))
744      (c-forward-syntactic-ws limit)
745      (c-font-lock-declarators limit t (eq prop 'c-decl-type-start))))
746
747  nil)
748
749(defun c-font-lock-<>-arglists (limit)
750  ;; This function will be called from font-lock for a region bounded by POINT
751  ;; and LIMIT, as though it were to identify a keyword for
752  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
753  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
754  ;; Fontification".
755  ;;
756  ;; Fontify types and references in names containing angle bracket
757  ;; arglists from the point to LIMIT.  Note that
758  ;; `c-font-lock-declarations' already has handled many of them.
759  ;;
760  ;; This function might do hidden buffer changes.
761
762  (let (;; The font-lock package in Emacs is known to clobber
763	;; `parse-sexp-lookup-properties' (when it exists).
764	(parse-sexp-lookup-properties
765	 (cc-eval-when-compile
766	   (boundp 'parse-sexp-lookup-properties)))
767	(c-parse-and-markup-<>-arglists t)
768	c-restricted-<>-arglists
769	id-start id-end id-face pos kwd-sym)
770
771    (while (and (< (point) limit)
772		(re-search-forward c-opt-<>-arglist-start limit t))
773
774      (setq id-start (match-beginning 1)
775	    id-end (match-end 1)
776	    pos (point))
777
778      (goto-char id-start)
779      (unless (c-skip-comments-and-strings limit)
780	(setq kwd-sym nil
781	      c-restricted-<>-arglists nil
782	      id-face (get-text-property id-start 'face))
783
784	(if (cond
785	     ((eq id-face 'font-lock-type-face)
786	      ;; The identifier got the type face so it has already been
787	      ;; handled in `c-font-lock-declarations'.
788	      nil)
789
790	     ((eq id-face 'font-lock-keyword-face)
791	      (when (looking-at c-opt-<>-sexp-key)
792		;; There's a special keyword before the "<" that tells
793		;; that it's an angle bracket arglist.
794		(setq kwd-sym (c-keyword-sym (match-string 1)))))
795
796	     (t
797	      ;; There's a normal identifier before the "<".  If we're not in
798	      ;; a declaration context then we set `c-restricted-<>-arglists'
799	      ;; to avoid recognizing templates in function calls like "foo (a
800	      ;; < b, c > d)".
801	      (c-backward-syntactic-ws)
802	      (when (and (memq (char-before) '(?\( ?,))
803			 (not (eq (get-text-property (1- (point)) 'c-type)
804				  'c-decl-arg-start)))
805		(setq c-restricted-<>-arglists t))
806	      t))
807
808	    (progn
809	      (goto-char (1- pos))
810	      ;; Check for comment/string both at the identifier and
811	      ;; at the "<".
812	      (unless (c-skip-comments-and-strings limit)
813
814		(c-fontify-types-and-refs ()
815		  (when (c-forward-<>-arglist (c-keyword-member
816					       kwd-sym 'c-<>-type-kwds))
817		    (when (and c-opt-identifier-concat-key
818			       (not (get-text-property id-start 'face)))
819		      (c-forward-syntactic-ws)
820		      (if (looking-at c-opt-identifier-concat-key)
821			  (c-put-font-lock-face id-start id-end
822						c-reference-face-name)
823			(c-put-font-lock-face id-start id-end
824					      'font-lock-type-face)))))
825
826		(goto-char pos)))
827	  (goto-char pos)))))
828  nil)
829
830(defun c-font-lock-declarators (limit list types)
831  ;; Assuming the point is at the start of a declarator in a
832  ;; declaration, fontify it.  If LIST is non-nil, fontify also all
833  ;; following declarators in a comma separated list (e.g.  "foo" and
834  ;; "bar" in "int foo = 17, bar;").  Stop at LIMIT.  If TYPES is
835  ;; non-nil, fontify all identifiers as types.  Nil is always
836  ;; returned.
837  ;;
838  ;; This function might do hidden buffer changes.
839
840  ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
841  (c-fontify-types-and-refs
842      ((pos (point)) next-pos id-start id-end
843       paren-depth
844       id-face got-init
845       c-last-identifier-range
846       (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
847
848    (while (and
849	    pos
850	    (< (point) limit)
851
852	    (let (got-identifier)
853	      (setq paren-depth 0)
854	      ;; Skip over type decl prefix operators.  (Note similar
855	      ;; code in `c-forward-decl-or-cast-1'.)
856	      (while (and (looking-at c-type-decl-prefix-key)
857			  (if (and (c-major-mode-is 'c++-mode)
858				   (match-beginning 2))
859			      ;; If the second submatch matches in C++ then
860			      ;; we're looking at an identifier that's a
861			      ;; prefix only if it specifies a member pointer.
862			      (progn
863				(setq id-start (point))
864				(c-forward-name)
865				(if (looking-at "\\(::\\)")
866				    ;; We only check for a trailing "::" and
867				    ;; let the "*" that should follow be
868				    ;; matched in the next round.
869				    t
870				  ;; It turned out to be the real identifier,
871				  ;; so flag that and stop.
872				  (setq got-identifier t)
873				  nil))
874			    t))
875		(if (eq (char-after) ?\()
876		    (progn
877		      (setq paren-depth (1+ paren-depth))
878		      (forward-char))
879		  (goto-char (match-end 1)))
880		(c-forward-syntactic-ws))
881
882	      ;; If we didn't pass the identifier above already, do it now.
883	      (unless got-identifier
884		(setq id-start (point))
885		(c-forward-name))
886	      (setq id-end (point))
887
888	      (/= id-end pos))
889
890	    ;; Skip out of the parens surrounding the identifier.
891	    (or (= paren-depth 0)
892		(c-safe (goto-char (scan-lists (point) 1 paren-depth))))
893
894	    (<= (point) limit)
895
896	    (progn
897	      (when (looking-at c-decl-hangon-key)
898		(c-forward-keyword-clause 1))
899	      (<= (point) limit))
900
901	    ;; Search syntactically to the end of the declarator (";",
902	    ;; ",", a closen paren, eob etc) or to the beginning of an
903	    ;; initializer or function prototype ("=" or "\\s\(").
904	    ;; Note that the open paren will match array specs in
905	    ;; square brackets, and we treat them as initializers too.
906	    (c-syntactic-re-search-forward
907	     "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t))
908
909      (setq next-pos (match-beginning 0)
910	    id-face (if (and (eq (char-after next-pos) ?\()
911			     (let (c-last-identifier-range)
912			       (save-excursion
913				 (goto-char next-pos)
914				 (c-at-toplevel-p))))
915			'font-lock-function-name-face
916		      'font-lock-variable-name-face)
917	    got-init (and (match-beginning 1)
918			  (char-after (match-beginning 1))))
919
920      (if types
921	  ;; Register and fontify the identifer as a type.
922	  (let ((c-promote-possible-types t))
923	    (goto-char id-start)
924	    (c-forward-type))
925	;; Fontify the last symbol in the identifier if it isn't fontified
926	;; already.  The check is necessary only in certain cases where this
927	;; function is used "sloppily", e.g. in `c-simple-decl-matchers'.
928	(when (and c-last-identifier-range
929		   (not (get-text-property (car c-last-identifier-range)
930					   'face)))
931	  (c-put-font-lock-face (car c-last-identifier-range)
932				(cdr c-last-identifier-range)
933				id-face)))
934
935      (goto-char next-pos)
936      (setq pos nil)
937      (when list
938	;; Jump past any initializer or function prototype to see if
939	;; there's a ',' to continue at.
940
941	(cond ((eq id-face 'font-lock-function-name-face)
942	       ;; Skip a parenthesized initializer (C++) or a function
943	       ;; prototype.
944	       (if (c-safe (c-forward-sexp 1) t)
945		   (c-forward-syntactic-ws limit)
946		 (goto-char limit)))
947
948	      (got-init
949	       ;; Skip an initializer expression.  If we're at a '='
950	       ;; then accept a brace list directly after it to cope
951	       ;; with array initializers.  Otherwise stop at braces
952	       ;; to avoid going past full function and class blocks.
953	       (and (if (and (eq got-init ?=)
954			     (= (c-forward-token-2 1 nil limit) 0)
955			     (looking-at "{"))
956			(c-safe (c-forward-sexp) t)
957		      t)
958		    ;; FIXME: Should look for c-decl-end markers here;
959		    ;; we might go far into the following declarations
960		    ;; in e.g. ObjC mode (see e.g. methods-4.m).
961		    (c-syntactic-re-search-forward "[;,{]" limit 'move t)
962		    (backward-char)))
963
964	      (t (c-forward-syntactic-ws limit)))
965
966	;; If a ',' is found we set pos to the next declarator and iterate.
967	(when (and (< (point) limit) (looking-at ","))
968	  (c-put-char-property (point) 'c-type separator-prop)
969	  (forward-char)
970	  (c-forward-syntactic-ws limit)
971	  (setq pos (point))))))
972  nil)
973
974(defconst c-font-lock-maybe-decl-faces
975  ;; List of faces that might be put at the start of a type when
976  ;; `c-font-lock-declarations' runs.  This needs to be evaluated to
977  ;; ensure that face name aliases in Emacs are resolved.
978  (list nil
979	font-lock-type-face
980	c-reference-face-name
981	font-lock-keyword-face))
982
983(defun c-font-lock-declarations (limit)
984  ;; This function will be called from font-lock for a region bounded by POINT
985  ;; and LIMIT, as though it were to identify a keyword for
986  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
987  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
988  ;; Fontification".
989  ;;
990  ;; Fontify all the declarations, casts and labels from the point to LIMIT.
991  ;; Assumes that strings and comments have been fontified already.
992  ;;
993  ;; This function might do hidden buffer changes.
994
995  ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
996
997  (save-restriction
998    (let (;; The position where `c-find-decl-spots' stopped.
999	  start-pos
1000	  ;; 'decl if we're in an arglist containing declarations (but
1001	  ;; if `c-recognize-paren-inits' is set it might also be an
1002	  ;; initializer arglist), '<> if the arglist is of angle
1003	  ;; bracket type, 'arglist if it's some other arglist, or nil
1004	  ;; if not in an arglist at all.
1005	  context
1006	  ;; The position of the next token after the closing paren of
1007	  ;; the last detected cast.
1008	  last-cast-end
1009	  ;; The result from `c-forward-decl-or-cast-1'.
1010	  decl-or-cast
1011	  ;; The maximum of the end positions of all the checked type
1012	  ;; decl expressions in the successfully identified
1013	  ;; declarations.  The position might be either before or
1014	  ;; after the syntactic whitespace following the last token
1015	  ;; in the type decl expression.
1016	  (max-type-decl-end 0)
1017	  ;; Same as `max-type-decl-*', but used when we're before
1018	  ;; `token-pos'.
1019	  (max-type-decl-end-before-token 0)
1020	  ;; Set according to the context to direct the heuristics for
1021	  ;; recognizing C++ templates.
1022	  c-restricted-<>-arglists
1023	  ;; Turn on recording of identifier ranges in
1024	  ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
1025	  ;; later fontification.
1026	  (c-record-type-identifiers t)
1027	  label-type
1028	  c-record-ref-identifiers
1029	  ;; Make `c-forward-type' calls mark up template arglists if
1030	  ;; it finds any.  That's necessary so that we later will
1031	  ;; stop inside them to fontify types there.
1032	  (c-parse-and-markup-<>-arglists t)
1033	  ;; The font-lock package in Emacs is known to clobber
1034	  ;; `parse-sexp-lookup-properties' (when it exists).
1035	  (parse-sexp-lookup-properties
1036	   (cc-eval-when-compile
1037	     (boundp 'parse-sexp-lookup-properties))))
1038
1039      ;; Below we fontify a whole declaration even when it crosses the limit,
1040      ;; to avoid gaps when lazy-lock fontifies the file a screenful at a
1041      ;; time.  That is however annoying during editing, e.g. the following is
1042      ;; a common situation while the first line is being written:
1043      ;;
1044      ;;     my_variable
1045      ;;     some_other_variable = 0;
1046      ;;
1047      ;; font-lock will put the limit at the beginning of the second line
1048      ;; here, and if we go past it we'll fontify "my_variable" as a type and
1049      ;; "some_other_variable" as an identifier, and the latter will not
1050      ;; correct itself until the second line is changed.  To avoid that we
1051      ;; narrow to the limit if the region to fontify is a single line.
1052      (narrow-to-region
1053       (point-min)
1054       (if (<= limit (c-point 'bonl))
1055	   (save-excursion
1056	     ;; Narrow after any operator chars following the limit though,
1057	     ;; since those characters can be useful in recognizing a
1058	     ;; declaration (in particular the '{' that opens a function body
1059	     ;; after the header).
1060	     (goto-char limit)
1061	     (skip-chars-forward c-nonsymbol-chars)
1062	     (point))
1063	 limit))
1064
1065      (c-find-decl-spots
1066       limit
1067       c-decl-start-re
1068       c-font-lock-maybe-decl-faces
1069
1070       (lambda (match-pos inside-macro)
1071	 (setq start-pos (point))
1072	 (when
1073	  ;; The result of the form below is true when we don't recognize a
1074	  ;; declaration or cast.
1075	  (if (and (eq (get-text-property (point) 'face)
1076		       'font-lock-keyword-face)
1077		   (looking-at c-not-decl-init-keywords))
1078	      ;; Don't do anything more if we're looking at a keyword that
1079	      ;; can't start a declaration.
1080	      t
1081
1082	    ;; Set `context'.  Look for "<" for the sake of C++-style template
1083	    ;; arglists.
1084	    (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<))
1085
1086		;; Find out the type of the arglist.
1087		(if (<= match-pos (point-min))
1088		    (setq context 'arglist)
1089		  (let ((type (c-get-char-property (1- match-pos) 'c-type)))
1090		    (cond ((eq type 'c-decl-arg-start)
1091			   ;; Got a cached hit in a declaration arglist.
1092			   (setq context 'decl))
1093			  ((or (eq type 'c-<>-arg-sep)
1094			       (eq (char-before match-pos) ?<))
1095			   ;; Inside an angle bracket arglist.
1096			   (setq context '<>))
1097			  (type
1098			   ;; Got a cached hit in some other type of arglist.
1099			   (setq context 'arglist))
1100			  ((if inside-macro
1101			       (< match-pos max-type-decl-end-before-token)
1102			     (< match-pos max-type-decl-end))
1103			   ;; The point is within the range of a previously
1104			   ;; encountered type decl expression, so the arglist
1105			   ;; is probably one that contains declarations.
1106			   ;; However, if `c-recognize-paren-inits' is set it
1107			   ;; might also be an initializer arglist.
1108			   (setq context 'decl)
1109			   ;; The result of this check is cached with a char
1110			   ;; property on the match token, so that we can look
1111			   ;; it up again when refontifying single lines in a
1112			   ;; multiline declaration.
1113			   (c-put-char-property (1- match-pos)
1114						'c-type 'c-decl-arg-start))
1115			  (t
1116			   (setq context 'arglist)))))
1117
1118	      (setq context nil))
1119
1120	    ;; If we're in a normal arglist context we don't want to
1121	    ;; recognize commas in nested angle bracket arglists since
1122	    ;; those commas could be part of our own arglist.
1123	    (setq c-restricted-<>-arglists (and c-recognize-<>-arglists
1124						(eq context 'arglist))
1125
1126		  ;; Now analyze the construct.
1127		  decl-or-cast (c-forward-decl-or-cast-1
1128				match-pos context last-cast-end))
1129
1130	    (if (not decl-or-cast)
1131		;; False alarm.  Return t to go on to the next check.
1132		t
1133
1134	      (if (eq decl-or-cast 'cast)
1135		  ;; Save the position after the previous cast so we can feed
1136		  ;; it to `c-forward-decl-or-cast-1' in the next round.  That
1137		  ;; helps it discover cast chains like "(a) (b) c".
1138		  (setq last-cast-end (point))
1139
1140		;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1141		;; under the assumption that we're after the first type decl
1142		;; expression in the declaration now.  That's not really true;
1143		;; we could also be after a parenthesized initializer
1144		;; expression in C++, but this is only used as a last resort
1145		;; to slant ambiguous expression/declarations, and overall
1146		;; it's worth the risk to occasionally fontify an expression
1147		;; as a declaration in an initializer expression compared to
1148		;; getting ambiguous things in normal function prototypes
1149		;; fontified as expressions.
1150		(if inside-macro
1151		    (when (> (point) max-type-decl-end-before-token)
1152		      (setq max-type-decl-end-before-token (point)))
1153		  (when (> (point) max-type-decl-end)
1154		    (setq max-type-decl-end (point))))
1155
1156		;; Back up to the type to fontify the declarator(s).
1157		(goto-char (car decl-or-cast))
1158
1159		(let ((decl-list
1160		       (if context
1161			   ;; Should normally not fontify a list of
1162			   ;; declarators inside an arglist, but the first
1163			   ;; argument in the ';' separated list of a "for"
1164			   ;; statement is an exception.
1165			   (when (eq (char-before match-pos) ?\()
1166			     (save-excursion
1167			       (goto-char (1- match-pos))
1168			       (c-backward-syntactic-ws)
1169			       (and (c-simple-skip-symbol-backward)
1170				    (looking-at c-paren-stmt-key))))
1171			 t)))
1172
1173		  ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1174		  ;; before the first declarator if it's a list.
1175		  ;; `c-font-lock-declarators' handles the rest.
1176		  (when decl-list
1177		    (save-excursion
1178		      (c-backward-syntactic-ws)
1179		      (unless (bobp)
1180			(c-put-char-property (1- (point)) 'c-type
1181					     (if (cdr decl-or-cast)
1182						 'c-decl-type-start
1183					       'c-decl-id-start)))))
1184
1185		  (c-font-lock-declarators
1186		   (point-max) decl-list (cdr decl-or-cast))))
1187
1188	      ;; A cast or declaration has been successfully identified, so do
1189	      ;; all the fontification of types and refs that's been recorded.
1190	      (c-fontify-recorded-types-and-refs)
1191	      nil))
1192
1193	  ;; It was a false alarm.  Check if we're in a label (or other
1194	  ;; construct with `:' except bitfield) instead.
1195	  (goto-char start-pos)
1196	  (when (setq label-type (c-forward-label t match-pos nil))
1197	    ;; Can't use `c-fontify-types-and-refs' here since we
1198	    ;; use the label face at times.
1199	    (cond ((eq label-type 'goto-target)
1200		   (c-put-font-lock-face (caar c-record-ref-identifiers)
1201					 (cdar c-record-ref-identifiers)
1202					 c-label-face-name))
1203		  ((eq label-type 'qt-1kwd-colon)
1204		   (c-put-font-lock-face (caar c-record-ref-identifiers)
1205					 (cdar c-record-ref-identifiers)
1206					 'font-lock-keyword-face))
1207		  ((eq label-type 'qt-2kwds-colon)
1208		   (mapc
1209		    (lambda (kwd)
1210		      (c-put-font-lock-face (car kwd) (cdr kwd)
1211					    'font-lock-keyword-face))
1212		    c-record-ref-identifiers)))
1213	    (setq c-record-ref-identifiers nil)
1214	    ;; `c-forward-label' has probably added a `c-decl-end'
1215	    ;; marker, so return t to `c-find-decl-spots' to signal
1216	    ;; that.
1217	    t))))
1218
1219      nil)))
1220
1221(c-lang-defconst c-simple-decl-matchers
1222  "Simple font lock matchers for types and declarations.  These are used
1223on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1224
1225  t `(;; Objective-C methods.
1226      ,@(when (c-major-mode-is 'objc-mode)
1227	  `((,(c-lang-const c-opt-method-key)
1228	     (,(byte-compile
1229		(lambda (limit)
1230		  (let (;; The font-lock package in Emacs is known to clobber
1231			;; `parse-sexp-lookup-properties' (when it exists).
1232			(parse-sexp-lookup-properties
1233			 (cc-eval-when-compile
1234			   (boundp 'parse-sexp-lookup-properties))))
1235		    (save-restriction
1236		      (narrow-to-region (point-min) limit)
1237		      (c-font-lock-objc-method)))
1238		  nil))
1239	      (goto-char (match-end 1))))))
1240
1241      ;; Fontify all type names and the identifiers in the
1242      ;; declarations they might start.  Use eval here since
1243      ;; `c-known-type-key' gets its value from
1244      ;; `*-font-lock-extra-types' on mode init.
1245      (eval . (list ,(c-make-font-lock-search-function
1246		      'c-known-type-key
1247		      '(1 'font-lock-type-face t)
1248		      '((c-font-lock-declarators limit t nil)
1249			(save-match-data
1250			  (goto-char (match-end 1))
1251			  (c-forward-syntactic-ws))
1252			(goto-char (match-end 1))))))
1253
1254      ;; Fontify types preceded by `c-type-prefix-kwds' and the
1255      ;; identifiers in the declarations they might start.
1256      ,@(when (c-lang-const c-type-prefix-kwds)
1257	  (let* ((prefix-re (c-make-keywords-re nil
1258			      (c-lang-const c-type-prefix-kwds)))
1259		 (type-match (+ 2
1260				(regexp-opt-depth prefix-re)
1261				(c-lang-const c-simple-ws-depth))))
1262	    `((,(c-make-font-lock-search-function
1263		 (concat "\\<\\(" prefix-re "\\)" ; 1
1264			 (c-lang-const c-simple-ws) "+"
1265			 (concat "\\("	; 2 + prefix-re + c-simple-ws
1266				 (c-lang-const c-symbol-key)
1267				 "\\)"))
1268		 `(,type-match
1269		   'font-lock-type-face t)
1270		 `((c-font-lock-declarators limit t nil)
1271		   (save-match-data
1272		     (goto-char (match-end ,type-match))
1273		     (c-forward-syntactic-ws))
1274		   (goto-char (match-end ,type-match))))))))
1275
1276      ;; Fontify special declarations that lacks a type.
1277      ,@(when (c-lang-const c-typeless-decl-kwds)
1278	  `((,(c-make-font-lock-search-function
1279	       (concat "\\<\\("
1280		       (regexp-opt (c-lang-const c-typeless-decl-kwds))
1281		       "\\)\\>")
1282	       '((c-font-lock-declarators limit t nil)
1283		 (save-match-data
1284		   (goto-char (match-end 1))
1285		   (c-forward-syntactic-ws))
1286		 (goto-char (match-end 1)))))))
1287
1288      ;; Fontify generic colon labels in languages that support them.
1289      ,@(when (c-lang-const c-recognize-colon-labels)
1290	  `(c-font-lock-labels))))
1291
1292(c-lang-defconst c-complex-decl-matchers
1293  "Complex font lock matchers for types and declarations.  Used on level
12943 and higher."
1295
1296  ;; Note: This code in this form dumps a number of funtions into the
1297  ;; resulting constant, `c-matchers-3'.  At run time, font lock will call
1298  ;; each of them as a "FUNCTION" (see Elisp page "Search-based
1299  ;; Fontification").  The font lock region is delimited by POINT and the
1300  ;; single parameter, LIMIT.  Each of these functions returns NIL (thus
1301  ;; inhibiting spurious font-lock-keyword-face highlighting and another
1302  ;; call).
1303
1304  t `(;; Initialize some things before the search functions below.
1305      c-font-lock-complex-decl-prepare
1306
1307      ,@(if (c-major-mode-is 'objc-mode)
1308	    ;; Fontify method declarations in Objective-C, but first
1309	    ;; we have to put the `c-decl-end' `c-type' property on
1310	    ;; all the @-style directives that haven't been handled in
1311	    ;; `c-basic-matchers-before'.
1312	    `(,(c-make-font-lock-search-function
1313		(c-make-keywords-re t
1314		  ;; Exclude "@class" since that directive ends with a
1315		  ;; semicolon anyway.
1316		  (delete "@class"
1317			  (append (c-lang-const c-protection-kwds)
1318				  (c-lang-const c-other-decl-kwds)
1319				  nil)))
1320		'((c-put-char-property (1- (match-end 1))
1321				       'c-type 'c-decl-end)))
1322	      c-font-lock-objc-methods))
1323
1324      ;; Fontify all declarations, casts and normal labels.
1325      c-font-lock-declarations
1326
1327      ;; Fontify angle bracket arglists like templates in C++.
1328      ,@(when (c-lang-const c-recognize-<>-arglists)
1329	  `(c-font-lock-<>-arglists))
1330
1331      ;; The first two rules here mostly find occurences that
1332      ;; `c-font-lock-declarations' has found already, but not
1333      ;; declarations containing blocks in the type (see note below).
1334      ;; It's also useful to fontify these everywhere to show e.g. when
1335      ;; a type keyword is accidentally used as an identifier.
1336
1337      ;; Fontify basic types.
1338      ,(let ((re (c-make-keywords-re nil
1339		   (c-lang-const c-primitive-type-kwds))))
1340	 (if (c-major-mode-is 'pike-mode)
1341	     ;; No symbol is a keyword after "->" in Pike.
1342	     `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
1343			"\\<\\(" re "\\)\\>")
1344	       2 font-lock-type-face)
1345	   `(,(concat "\\<\\(" re "\\)\\>")
1346	     1 'font-lock-type-face)))
1347
1348      ;; Fontify types preceded by `c-type-prefix-kwds'.
1349      ,@(when (c-lang-const c-type-prefix-kwds)
1350	  `((,(byte-compile
1351	       `(lambda (limit)
1352		  (c-fontify-types-and-refs
1353		      ((c-promote-possible-types t)
1354		       ;; The font-lock package in Emacs is known to clobber
1355		       ;; `parse-sexp-lookup-properties' (when it exists).
1356		       (parse-sexp-lookup-properties
1357			(cc-eval-when-compile
1358			  (boundp 'parse-sexp-lookup-properties))))
1359		    (save-restriction
1360		      ;; Narrow to avoid going past the limit in
1361		      ;; `c-forward-type'.
1362		      (narrow-to-region (point) limit)
1363		      (while (re-search-forward
1364			      ,(concat "\\<\\("
1365				       (c-make-keywords-re nil
1366					 (c-lang-const c-type-prefix-kwds))
1367				       "\\)\\>")
1368			      limit t)
1369			(unless (c-skip-comments-and-strings limit)
1370			  (c-forward-syntactic-ws)
1371			  ;; Handle prefix declaration specifiers.
1372			  (when (looking-at c-prefix-spec-kwds-re)
1373			    (c-forward-keyword-clause 1))
1374			  ,(if (c-major-mode-is 'c++-mode)
1375			       `(when (and (c-forward-type)
1376					   (eq (char-after) ?=))
1377				  ;; In C++ we additionally check for a "class
1378				  ;; X = Y" construct which is used in
1379				  ;; templates, to fontify Y as a type.
1380				  (forward-char)
1381				  (c-forward-syntactic-ws)
1382				  (c-forward-type))
1383			     `(c-forward-type))
1384			  )))))))))
1385
1386      ;; Fontify symbols after closing braces as declaration
1387      ;; identifiers under the assumption that they are part of
1388      ;; declarations like "class Foo { ... } foo;".  It's too
1389      ;; expensive to check this accurately by skipping past the
1390      ;; brace block, so we use the heuristic that it's such a
1391      ;; declaration if the first identifier is on the same line as
1392      ;; the closing brace.  `c-font-lock-declarations' will later
1393      ;; override it if it turns out to be an new declaration, but
1394      ;; it will be wrong if it's an expression (see the test
1395      ;; decls-8.cc).
1396      ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
1397	  `((,(c-make-font-lock-search-function
1398	       (concat "}"
1399		       (c-lang-const c-single-line-syntactic-ws)
1400		       "\\("		; 1 + c-single-line-syntactic-ws-depth
1401		       (c-lang-const c-type-decl-prefix-key)
1402		       "\\|"
1403		       (c-lang-const c-symbol-key)
1404		       "\\)")
1405	       `((c-font-lock-declarators limit t nil)
1406		 (progn
1407		   (c-put-char-property (match-beginning 0) 'c-type
1408					'c-decl-id-start)
1409		   (goto-char (match-beginning
1410			       ,(1+ (c-lang-const
1411				     c-single-line-syntactic-ws-depth)))))
1412		 (goto-char (match-end 0)))))))
1413
1414      ;; Fontify the type in C++ "new" expressions.
1415      ,@(when (c-major-mode-is 'c++-mode)
1416	  ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)"
1417	  ;; (see Elisp page "Search-based Fontification").
1418	  `(("\\<new\\>"
1419	     (c-font-lock-c++-new))))
1420      ))
1421
1422(defun c-font-lock-labels (limit)
1423  ;; Fontify all statement labels from the point to LIMIT.  Assumes
1424  ;; that strings and comments have been fontified already.  Nil is
1425  ;; always returned.
1426  ;;
1427  ;; Note: This function is only used on decoration level 2; this is
1428  ;; taken care of directly by the gargantuan
1429  ;; `c-font-lock-declarations' on higher levels.
1430  ;;
1431  ;; This function might do hidden buffer changes.
1432
1433  (let (continue-pos id-start
1434	;; The font-lock package in Emacs is known to clobber
1435	;; `parse-sexp-lookup-properties' (when it exists).
1436	(parse-sexp-lookup-properties
1437	 (cc-eval-when-compile
1438	   (boundp 'parse-sexp-lookup-properties))))
1439
1440    (while (re-search-forward ":[^:]" limit t)
1441      (setq continue-pos (point))
1442      (goto-char (match-beginning 0))
1443      (unless (c-skip-comments-and-strings limit)
1444
1445	(c-backward-syntactic-ws)
1446	(and (setq id-start (c-on-identifier))
1447
1448	     (not (get-text-property id-start 'face))
1449
1450	     (progn
1451	       (goto-char id-start)
1452	       (c-backward-syntactic-ws)
1453	       (or
1454		;; Check for a char that precedes a statement.
1455		(memq (char-before) '(?\} ?\{ ?\;))
1456		;; Check for a preceding label.  We exploit the font
1457		;; locking made earlier by this function.
1458		(and (eq (char-before) ?:)
1459		     (progn
1460		       (backward-char)
1461		       (c-backward-syntactic-ws)
1462		       (not (bobp)))
1463		     (eq (get-text-property (1- (point)) 'face)
1464			 c-label-face-name))
1465		;; Check for a keyword that precedes a statement.
1466		(c-after-conditional)))
1467
1468	     (progn
1469	       ;; Got a label.
1470	       (goto-char id-start)
1471	       (looking-at c-symbol-key)
1472	       (c-put-font-lock-face (match-beginning 0) (match-end 0)
1473				     c-label-face-name)))
1474
1475	(goto-char continue-pos))))
1476  nil)
1477
1478(c-lang-defconst c-basic-matchers-after
1479  "Font lock matchers for various things that should be fontified after
1480generic casts and declarations are fontified.  Used on level 2 and
1481higher."
1482
1483  t `(;; Fontify the identifiers inside enum lists.  (The enum type
1484      ;; name is handled by `c-simple-decl-matchers' or
1485      ;; `c-complex-decl-matchers' below.
1486      ,@(when (c-lang-const c-brace-id-list-kwds)
1487	  `((,(c-make-font-lock-search-function
1488	       (concat
1489		"\\<\\("
1490		(c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
1491		"\\)\\>"
1492		;; Disallow various common punctuation chars that can't come
1493		;; before the '{' of the enum list, to avoid searching too far.
1494		"[^\]\[{}();,/#=]*"
1495		"{")
1496	       '((c-font-lock-declarators limit t nil)
1497		 (save-match-data
1498		   (goto-char (match-end 0))
1499		   (c-put-char-property (1- (point)) 'c-type
1500					'c-decl-id-start)
1501		   (c-forward-syntactic-ws))
1502		 (goto-char (match-end 0)))))))
1503
1504	;; Fontify labels after goto etc.
1505	,@(when (c-lang-const c-before-label-kwds)
1506	  `(;; (Got three different interpretation levels here,
1507	    ;; which makes it a bit complicated: 1) The backquote
1508	    ;; stuff is expanded when compiled or loaded, 2) the
1509	    ;; eval form is evaluated at font-lock setup (to
1510	    ;; substitute c-label-face-name correctly), and 3) the
1511	    ;; resulting structure is interpreted during
1512	    ;; fontification.)
1513	    (eval
1514	     . ,(let* ((c-before-label-re
1515			(c-make-keywords-re nil
1516			  (c-lang-const c-before-label-kwds))))
1517		  `(list
1518		    ,(concat "\\<\\(" c-before-label-re "\\)\\>"
1519			     "\\s *"
1520			     "\\("	; identifier-offset
1521			     (c-lang-const c-symbol-key)
1522			     "\\)")
1523		    (list ,(+ (regexp-opt-depth c-before-label-re) 2)
1524			  c-label-face-name nil t))))))
1525
1526      ;; Fontify the clauses after various keywords.
1527      ,@(when (or (c-lang-const c-type-list-kwds)
1528		  (c-lang-const c-ref-list-kwds)
1529		  (c-lang-const c-colon-type-list-kwds)
1530		  (c-lang-const c-paren-type-kwds))
1531	  `((,(c-make-font-lock-search-function
1532	       (concat "\\<\\("
1533		       (c-make-keywords-re nil
1534			 (append (c-lang-const c-type-list-kwds)
1535				 (c-lang-const c-ref-list-kwds)
1536				 (c-lang-const c-colon-type-list-kwds)
1537				 (c-lang-const c-paren-type-kwds)))
1538		       "\\)\\>")
1539	       '((c-fontify-types-and-refs ((c-promote-possible-types t))
1540		   (c-forward-keyword-clause 1)
1541		   (if (> (point) limit) (goto-char limit))))))))
1542      ))
1543
1544(c-lang-defconst c-matchers-1
1545  t (c-lang-const c-cpp-matchers))
1546
1547(c-lang-defconst c-matchers-2
1548  t (append (c-lang-const c-matchers-1)
1549	    (c-lang-const c-basic-matchers-before)
1550	    (c-lang-const c-simple-decl-matchers)
1551	    (c-lang-const c-basic-matchers-after)))
1552
1553(c-lang-defconst c-matchers-3
1554  t (append (c-lang-const c-matchers-1)
1555	    (c-lang-const c-basic-matchers-before)
1556	    (c-lang-const c-complex-decl-matchers)
1557	    (c-lang-const c-basic-matchers-after)))
1558
1559(defun c-compose-keywords-list (base-list)
1560  ;; Incorporate the font lock keyword lists according to
1561  ;; `c-doc-comment-style' on the given keyword list and return it.
1562  ;; This is used in the function bindings of the
1563  ;; `*-font-lock-keywords-*' symbols since we have to build the list
1564  ;; when font-lock is initialized.
1565
1566  (unless (memq c-doc-face-name c-literal-faces)
1567    (setq c-literal-faces (cons c-doc-face-name c-literal-faces)))
1568
1569  (let* ((doc-keywords
1570	  (if (consp (car-safe c-doc-comment-style))
1571	      (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
1572			    (assq 'other c-doc-comment-style)))
1573	    c-doc-comment-style))
1574	 (list (nconc (apply 'nconc
1575			     (mapcar
1576			      (lambda (doc-style)
1577				(let ((sym (intern
1578					    (concat (symbol-name doc-style)
1579						    "-font-lock-keywords"))))
1580				  (cond ((fboundp sym)
1581					 (funcall sym))
1582					((boundp sym)
1583					 (append (eval sym) nil)))))
1584			      (if (listp doc-keywords)
1585				  doc-keywords
1586				(list doc-keywords))))
1587		      base-list)))
1588
1589    ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we
1590    ;; move it first since the doc comment font lockers might add
1591    ;; `c-type' text properties, so they have to be cleared before that.
1592    (when (memq 'c-font-lock-complex-decl-prepare list)
1593      (setq list (cons 'c-font-lock-complex-decl-prepare
1594		       (delq 'c-font-lock-complex-decl-prepare
1595			     (append list nil)))))
1596
1597    list))
1598
1599(defun c-override-default-keywords (def-var)
1600  ;; This is used to override the value on a `*-font-lock-keywords'
1601  ;; variable only if it's nil or has the same value as one of the
1602  ;; `*-font-lock-keywords-*' variables.  Older font-lock packages
1603  ;; define a default value for `*-font-lock-keywords' which we want
1604  ;; to override, but we should otoh avoid clobbering a user setting.
1605  ;; This heuristic for that isn't perfect, but I can't think of any
1606  ;; better. /mast
1607  (when (and (boundp def-var)
1608	     (memq (symbol-value def-var)
1609		   (cons nil
1610			 (mapcar
1611			  (lambda (suffix)
1612			    (let ((sym (intern (concat (symbol-name def-var)
1613						       suffix))))
1614			      (and (boundp sym) (symbol-value sym))))
1615			  '("-1" "-2" "-3")))))
1616    ;; The overriding is done by unbinding the variable so that the normal
1617    ;; defvar will install its default value later on.
1618    (makunbound def-var)))
1619
1620
1621;;; C.
1622
1623(c-override-default-keywords 'c-font-lock-keywords)
1624
1625(defconst c-font-lock-keywords-1 (c-lang-const c-matchers-1 c)
1626  "Minimal font locking for C mode.
1627Fontifies only preprocessor directives (in addition to the syntactic
1628fontification of strings and comments).")
1629
1630(defconst c-font-lock-keywords-2 (c-lang-const c-matchers-2 c)
1631  "Fast normal font locking for C mode.
1632In addition to `c-font-lock-keywords-1', this adds fontification of
1633keywords, simple types, declarations that are easy to recognize, the
1634user defined types on `c-font-lock-extra-types', and the doc comment
1635styles specified by `c-doc-comment-style'.")
1636
1637(defconst c-font-lock-keywords-3 (c-lang-const c-matchers-3 c)
1638  "Accurate normal font locking for C mode.
1639Like `c-font-lock-keywords-2' but detects declarations in a more
1640accurate way that works in most cases for arbitrary types without the
1641need for `c-font-lock-extra-types'.")
1642
1643(defvar c-font-lock-keywords c-font-lock-keywords-3
1644  "Default expressions to highlight in C mode.")
1645
1646(defun c-font-lock-keywords-2 ()
1647  (c-compose-keywords-list c-font-lock-keywords-2))
1648(defun c-font-lock-keywords-3 ()
1649  (c-compose-keywords-list c-font-lock-keywords-3))
1650(defun c-font-lock-keywords ()
1651  (c-compose-keywords-list c-font-lock-keywords))
1652
1653
1654;;; C++.
1655
1656(defun c-font-lock-c++-new (limit)
1657  ;; Assuming point is after a "new" word, check that it isn't inside
1658  ;; a string or comment, and if so try to fontify the type in the
1659  ;; allocation expression.  Nil is always returned.
1660  ;;
1661  ;; As usual, C++ takes the prize in coming up with a hard to parse
1662  ;; syntax. :P
1663  ;;
1664  ;; This function might do hidden buffer changes.
1665
1666  (unless (c-skip-comments-and-strings limit)
1667    (save-excursion
1668      (catch 'false-alarm
1669	;; A "new" keyword is followed by one to three expressions, where
1670	;; the type is the middle one, and the only required part.
1671	(let (expr1-pos expr2-pos
1672	      ;; Enable recording of identifier ranges in `c-forward-type'
1673	      ;; etc for later fontification.  Not using
1674	      ;; `c-fontify-types-and-refs' here since the ranges should
1675	      ;; be fontified selectively only when an allocation
1676	      ;; expression is successfully recognized.
1677	      (c-record-type-identifiers t)
1678	      c-record-ref-identifiers
1679	      ;; The font-lock package in Emacs is known to clobber
1680	      ;; `parse-sexp-lookup-properties' (when it exists).
1681	      (parse-sexp-lookup-properties
1682	       (cc-eval-when-compile
1683		 (boundp 'parse-sexp-lookup-properties))))
1684	  (c-forward-syntactic-ws)
1685
1686	  ;; The first placement arglist is always parenthesized, if it
1687	  ;; exists.
1688	  (when (eq (char-after) ?\()
1689	    (setq expr1-pos (1+ (point)))
1690	    (condition-case nil
1691		(c-forward-sexp)
1692	      (scan-error (throw 'false-alarm t)))
1693	    (c-forward-syntactic-ws))
1694
1695	  ;; The second expression is either a type followed by some "*" or
1696	  ;; "[...]" or similar, or a parenthesized type followed by a full
1697	  ;; identifierless declarator.
1698	  (setq expr2-pos (1+ (point)))
1699	  (cond ((eq (char-after) ?\())
1700		((let ((c-promote-possible-types t))
1701		   (c-forward-type)))
1702		(t (setq expr2-pos nil)))
1703
1704	  (when expr1-pos
1705	    (cond
1706	     ((not expr2-pos)
1707	      ;; No second expression, so the first has to be a
1708	      ;; parenthesized type.
1709	      (goto-char expr1-pos)
1710	      (let ((c-promote-possible-types t))
1711		(c-forward-type)))
1712
1713	     ((eq (char-before expr2-pos) ?\()
1714	      ;; Got two parenthesized expressions, so we have to look
1715	      ;; closer at them to decide which is the type.  No need to
1716	      ;; handle `c-record-ref-identifiers' since all references
1717	      ;; has already been handled by other fontification rules.
1718	      (let (expr1-res expr2-res)
1719
1720		(goto-char expr1-pos)
1721		(when (setq expr1-res (c-forward-type))
1722		  (unless (looking-at
1723			   (cc-eval-when-compile
1724			     (concat (c-lang-const c-symbol-start c++)
1725				     "\\|[*:\)\[]")))
1726		    ;; There's something after the would-be type that
1727		    ;; can't be there, so this is a placement arglist.
1728		    (setq expr1-res nil)))
1729
1730		(goto-char expr2-pos)
1731		(when (setq expr2-res (c-forward-type))
1732		  (unless (looking-at
1733			   (cc-eval-when-compile
1734			     (concat (c-lang-const c-symbol-start c++)
1735				     "\\|[*:\)\[]")))
1736		    ;; There's something after the would-be type that can't
1737		    ;; be there, so this is an initialization expression.
1738		    (setq expr2-res nil))
1739		  (when (and (c-go-up-list-forward)
1740			     (progn (c-forward-syntactic-ws)
1741				    (eq (char-after) ?\()))
1742		    ;; If there's a third initialization expression
1743		    ;; then the second one is the type, so demote the
1744		    ;; first match.
1745		    (setq expr1-res nil)))
1746
1747		;; We fontify the most likely type, with a preference for
1748		;; the first argument since a placement arglist is more
1749		;; unusual than an initializer.
1750		(cond ((memq expr1-res '(t known prefix)))
1751		      ((memq expr2-res '(t known prefix)))
1752		      ((eq expr1-res 'found)
1753		       (let ((c-promote-possible-types t))
1754			 (goto-char expr1-pos)
1755			 (c-forward-type)))
1756		      ((eq expr2-res 'found)
1757		       (let ((c-promote-possible-types t))
1758			 (goto-char expr2-pos)
1759			 (c-forward-type)))
1760		      ((and (eq expr1-res 'maybe) (not expr2-res))
1761		       (let ((c-promote-possible-types t))
1762			 (goto-char expr1-pos)
1763			 (c-forward-type)))
1764		      ((and (not expr1-res) (eq expr2-res 'maybe))
1765		       (let ((c-promote-possible-types t))
1766			 (goto-char expr2-pos)
1767			 (c-forward-type)))
1768		      ;; If both type matches are 'maybe then we're
1769		      ;; too uncertain to promote either of them.
1770		      )))))
1771
1772	  ;; Fontify the type that now is recorded in
1773	  ;; `c-record-type-identifiers', if any.
1774	  (c-fontify-recorded-types-and-refs)))))
1775  nil)
1776
1777(c-override-default-keywords 'c++-font-lock-keywords)
1778
1779(defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++)
1780  "Minimal font locking for C++ mode.
1781Fontifies only preprocessor directives (in addition to the syntactic
1782fontification of strings and comments).")
1783
1784(defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++)
1785  "Fast normal font locking for C++ mode.
1786In addition to `c++-font-lock-keywords-1', this adds fontification of
1787keywords, simple types, declarations that are easy to recognize, the
1788user defined types on `c++-font-lock-extra-types', and the doc comment
1789styles specified by `c-doc-comment-style'.")
1790
1791(defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++)
1792  "Accurate normal font locking for C++ mode.
1793Like `c++-font-lock-keywords-2' but detects declarations in a more
1794accurate way that works in most cases for arbitrary types without the
1795need for `c++-font-lock-extra-types'.")
1796
1797(defvar c++-font-lock-keywords c++-font-lock-keywords-3
1798  "Default expressions to highlight in C++ mode.")
1799
1800(defun c++-font-lock-keywords-2 ()
1801  (c-compose-keywords-list c++-font-lock-keywords-2))
1802(defun c++-font-lock-keywords-3 ()
1803  (c-compose-keywords-list c++-font-lock-keywords-3))
1804(defun c++-font-lock-keywords ()
1805  (c-compose-keywords-list c++-font-lock-keywords))
1806
1807
1808;;; Objective-C.
1809
1810(defun c-font-lock-objc-method ()
1811  ;; Assuming the point is after the + or - that starts an Objective-C
1812  ;; method declaration, fontify it.  This must be done before normal
1813  ;; casts, declarations and labels are fontified since they will get
1814  ;; false matches in these things.
1815  ;;
1816  ;; This function might do hidden buffer changes.
1817
1818  (c-fontify-types-and-refs
1819      ((first t)
1820       (c-promote-possible-types t))
1821
1822    (while (and
1823	    (progn
1824	      (c-forward-syntactic-ws)
1825
1826	      ;; An optional method type.
1827	      (if (eq (char-after) ?\()
1828		  (progn
1829		    (forward-char)
1830		    (c-forward-syntactic-ws)
1831		    (c-forward-type)
1832		    (prog1 (c-go-up-list-forward)
1833		      (c-forward-syntactic-ws)))
1834		t))
1835
1836	    ;; The name.  The first time it's the first part of
1837	    ;; the function name, the rest of the time it's an
1838	    ;; argument name.
1839	    (looking-at c-symbol-key)
1840	    (progn
1841	      (goto-char (match-end 0))
1842	      (c-put-font-lock-face (match-beginning 0)
1843				    (point)
1844				    (if first
1845					'font-lock-function-name-face
1846				      'font-lock-variable-name-face))
1847	      (c-forward-syntactic-ws)
1848
1849	      ;; Another optional part of the function name.
1850	      (when (looking-at c-symbol-key)
1851		(goto-char (match-end 0))
1852		(c-put-font-lock-face (match-beginning 0)
1853				      (point)
1854				      'font-lock-function-name-face)
1855		(c-forward-syntactic-ws))
1856
1857	      ;; There's another argument if a colon follows.
1858	      (eq (char-after) ?:)))
1859      (forward-char)
1860      (setq first nil))))
1861
1862(defun c-font-lock-objc-methods (limit)
1863  ;; Fontify method declarations in Objective-C.  Nil is always
1864  ;; returned.
1865  ;;
1866  ;; This function might do hidden buffer changes.
1867
1868  (let (;; The font-lock package in Emacs is known to clobber
1869	;; `parse-sexp-lookup-properties' (when it exists).
1870	(parse-sexp-lookup-properties
1871	 (cc-eval-when-compile
1872	   (boundp 'parse-sexp-lookup-properties))))
1873
1874    (c-find-decl-spots
1875     limit
1876     "[-+]"
1877     nil
1878     (lambda (match-pos inside-macro)
1879       (forward-char)
1880       (c-font-lock-objc-method))))
1881  nil)
1882
1883(c-override-default-keywords 'objc-font-lock-keywords)
1884
1885(defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc)
1886  "Minimal font locking for Objective-C mode.
1887Fontifies only compiler directives (in addition to the syntactic
1888fontification of strings and comments).")
1889
1890(defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc)
1891  "Fast normal font locking for Objective-C mode.
1892In addition to `objc-font-lock-keywords-1', this adds fontification of
1893keywords, simple types, declarations that are easy to recognize, the
1894user defined types on `objc-font-lock-extra-types', and the doc
1895comment styles specified by `c-doc-comment-style'.")
1896
1897(defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc)
1898  "Accurate normal font locking for Objective-C mode.
1899Like `objc-font-lock-keywords-2' but detects declarations in a more
1900accurate way that works in most cases for arbitrary types without the
1901need for `objc-font-lock-extra-types'.")
1902
1903(defvar objc-font-lock-keywords objc-font-lock-keywords-3
1904  "Default expressions to highlight in Objective-C mode.")
1905
1906(defun objc-font-lock-keywords-2 ()
1907  (c-compose-keywords-list objc-font-lock-keywords-2))
1908(defun objc-font-lock-keywords-3 ()
1909  (c-compose-keywords-list objc-font-lock-keywords-3))
1910(defun objc-font-lock-keywords ()
1911  (c-compose-keywords-list objc-font-lock-keywords))
1912
1913;; Kludge to override the default value that
1914;; `objc-font-lock-extra-types' might have gotten from the font-lock
1915;; package.  The value replaced here isn't relevant now anyway since
1916;; those types are builtin and therefore listed directly in
1917;; `c-primitive-type-kwds'.
1918(when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp)
1919	     '("BOOL" "Class" "IMP" "SEL"))
1920  (setq objc-font-lock-extra-types
1921	(cc-eval-when-compile (list (concat "[" c-upper "]\\sw*")))))
1922
1923
1924;;; Java.
1925
1926(c-override-default-keywords 'java-font-lock-keywords)
1927
1928(defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java)
1929  "Minimal font locking for Java mode.
1930Fontifies nothing except the syntactic fontification of strings and
1931comments.")
1932
1933(defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java)
1934  "Fast normal font locking for Java mode.
1935In addition to `java-font-lock-keywords-1', this adds fontification of
1936keywords, simple types, declarations that are easy to recognize, the
1937user defined types on `java-font-lock-extra-types', and the doc
1938comment styles specified by `c-doc-comment-style'.")
1939
1940(defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java)
1941  "Accurate normal font locking for Java mode.
1942Like `java-font-lock-keywords-2' but detects declarations in a more
1943accurate way that works in most cases for arbitrary types without the
1944need for `java-font-lock-extra-types'.")
1945
1946(defvar java-font-lock-keywords java-font-lock-keywords-3
1947  "Default expressions to highlight in Java mode.")
1948
1949(defun java-font-lock-keywords-2 ()
1950  (c-compose-keywords-list java-font-lock-keywords-2))
1951(defun java-font-lock-keywords-3 ()
1952  (c-compose-keywords-list java-font-lock-keywords-3))
1953(defun java-font-lock-keywords ()
1954  (c-compose-keywords-list java-font-lock-keywords))
1955
1956
1957;;; CORBA IDL.
1958
1959(c-override-default-keywords 'idl-font-lock-keywords)
1960
1961(defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl)
1962  "Minimal font locking for CORBA IDL mode.
1963Fontifies nothing except the syntactic fontification of strings and
1964comments.")
1965
1966(defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl)
1967  "Fast normal font locking for CORBA IDL mode.
1968In addition to `idl-font-lock-keywords-1', this adds fontification of
1969keywords, simple types, declarations that are easy to recognize, the
1970user defined types on `idl-font-lock-extra-types', and the doc comment
1971styles specified by `c-doc-comment-style'.")
1972
1973(defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl)
1974  "Accurate normal font locking for CORBA IDL mode.
1975Like `idl-font-lock-keywords-2' but detects declarations in a more
1976accurate way that works in most cases for arbitrary types without the
1977need for `idl-font-lock-extra-types'.")
1978
1979(defvar idl-font-lock-keywords idl-font-lock-keywords-3
1980  "Default expressions to highlight in CORBA IDL mode.")
1981
1982(defun idl-font-lock-keywords-2 ()
1983  (c-compose-keywords-list idl-font-lock-keywords-2))
1984(defun idl-font-lock-keywords-3 ()
1985  (c-compose-keywords-list idl-font-lock-keywords-3))
1986(defun idl-font-lock-keywords ()
1987  (c-compose-keywords-list idl-font-lock-keywords))
1988
1989
1990;;; Pike.
1991
1992(c-override-default-keywords 'pike-font-lock-keywords)
1993
1994(defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike)
1995  "Minimal font locking for Pike mode.
1996Fontifies only preprocessor directives (in addition to the syntactic
1997fontification of strings and comments).")
1998
1999(defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike)
2000  "Fast normal font locking for Pike mode.
2001In addition to `pike-font-lock-keywords-1', this adds fontification of
2002keywords, simple types, declarations that are easy to recognize, the
2003user defined types on `pike-font-lock-extra-types', and the doc
2004comment styles specified by `c-doc-comment-style'.")
2005
2006(defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike)
2007  "Accurate normal font locking for Pike mode.
2008Like `pike-font-lock-keywords-2' but detects declarations in a more
2009accurate way that works in most cases for arbitrary types without the
2010need for `pike-font-lock-extra-types'.")
2011
2012(defvar pike-font-lock-keywords pike-font-lock-keywords-3
2013  "Default expressions to highlight in Pike mode.")
2014
2015(defun pike-font-lock-keywords-2 ()
2016  (c-compose-keywords-list pike-font-lock-keywords-2))
2017(defun pike-font-lock-keywords-3 ()
2018  (c-compose-keywords-list pike-font-lock-keywords-3))
2019(defun pike-font-lock-keywords ()
2020  (c-compose-keywords-list pike-font-lock-keywords))
2021
2022
2023;;; Doc comments.
2024
2025(defun c-font-lock-doc-comments (prefix limit keywords)
2026  ;; Fontify the comments between the point and LIMIT whose start
2027  ;; matches PREFIX with `c-doc-face-name'.  Assumes comments have been
2028  ;; fontified with `font-lock-comment-face' already.  nil is always
2029  ;; returned.
2030  ;;
2031  ;; After the fontification of a matching comment, fontification
2032  ;; according to KEYWORDS is applied inside it.  It's a list like
2033  ;; `font-lock-keywords' except that anchored matches and eval
2034  ;; clauses aren't supported and that some abbreviated forms can't be
2035  ;; used.  The buffer is narrowed to the comment while KEYWORDS is
2036  ;; applied; leading comment starters are included but trailing
2037  ;; comment enders for block comment are not.
2038  ;;
2039  ;; Note that faces added through KEYWORDS should never replace the
2040  ;; existing `c-doc-face-name' face since the existence of that face
2041  ;; is used as a flag in other code to skip comments.
2042  ;;
2043  ;; This function might do hidden buffer changes.
2044
2045  (let (comment-beg region-beg)
2046    (if (eq (get-text-property (point) 'face)
2047	    'font-lock-comment-face)
2048	;; Handle the case when the fontified region starts inside a
2049	;; comment.
2050	(let ((range (c-literal-limits)))
2051	  (setq region-beg (point))
2052	  (when range
2053	    (goto-char (car range)))
2054	  (when (looking-at prefix)
2055	    (setq comment-beg (point)))))
2056
2057    (while (or
2058	    comment-beg
2059
2060	    ;; Search for the prefix until a match is found at the start
2061	    ;; of a comment.
2062	    (while (when (re-search-forward prefix limit t)
2063		     (setq comment-beg (match-beginning 0))
2064		     (or (not (c-got-face-at comment-beg
2065					     c-literal-faces))
2066			 (and (/= comment-beg (point-min))
2067			      (c-got-face-at (1- comment-beg)
2068					     c-literal-faces))))
2069	      (setq comment-beg nil))
2070	    (setq region-beg comment-beg))
2071
2072      (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t)
2073	  ;; Collect a sequence of doc style line comments.
2074	  (progn
2075	    (goto-char comment-beg)
2076	    (while (and (progn
2077			  (c-forward-single-comment)
2078			  (skip-syntax-forward " ")
2079			  (< (point) limit))
2080			(looking-at prefix))))
2081	(goto-char comment-beg)
2082	(c-forward-single-comment))
2083      (if (> (point) limit) (goto-char limit))
2084      (setq comment-beg nil)
2085
2086      (let ((region-end (point))
2087	    (keylist keywords) keyword matcher highlights)
2088	(c-put-font-lock-face region-beg region-end c-doc-face-name)
2089	(save-restriction
2090	  ;; Narrow to the doc comment.  Among other things, this
2091	  ;; helps by making "^" match at the start of the comment.
2092	  ;; Do not include a trailing block comment ender, though.
2093	  (and (> region-end (1+ region-beg))
2094	       (progn (goto-char region-end)
2095		      (backward-char 2)
2096		      (looking-at "\\*/"))
2097	       (setq region-end (point)))
2098	  (narrow-to-region region-beg region-end)
2099
2100	  (while keylist
2101	    (setq keyword (car keylist)
2102		  keylist (cdr keylist)
2103		  matcher (car keyword))
2104	    (goto-char region-beg)
2105	    (while (if (stringp matcher)
2106		       (re-search-forward matcher region-end t)
2107		     (funcall matcher region-end))
2108	      (setq highlights (cdr keyword))
2109	      (if (consp (car highlights))
2110		  (while highlights
2111		    (font-lock-apply-highlight (car highlights))
2112		    (setq highlights (cdr highlights)))
2113		(font-lock-apply-highlight highlights))))
2114
2115	  (goto-char region-end)))))
2116  nil)
2117(put 'c-font-lock-doc-comments 'lisp-indent-function 2)
2118
2119(defun c-find-invalid-doc-markup (regexp limit)
2120  ;; Used to fontify invalid markup in doc comments after the correct
2121  ;; ones have been fontified: Find the first occurence of REGEXP
2122  ;; between the point and LIMIT that only is fontified with
2123  ;; `c-doc-face-name'.  If a match is found then submatch 0 surrounds
2124  ;; the first char and t is returned, otherwise nil is returned.
2125  ;;
2126  ;; This function might do hidden buffer changes.
2127  (let (start)
2128    (while (if (re-search-forward regexp limit t)
2129	       (not (eq (get-text-property
2130			 (setq start (match-beginning 0)) 'face)
2131			c-doc-face-name))
2132	     (setq start nil)))
2133    (when start
2134      (store-match-data (list (copy-marker start)
2135			      (copy-marker (1+ start))))
2136      t)))
2137
2138;; GtkDoc patterns contributed by Masatake YAMATO <jet@gyve.org>.
2139
2140(defconst gtkdoc-font-lock-doc-comments
2141  (let ((symbol "[a-zA-Z0-9_]+")
2142	(header "^ \\* "))
2143    `((,(concat header "\\("     symbol "\\):[ \t]*$")
2144       1 ,c-doc-markup-face-name prepend nil)
2145      (,(concat                  symbol     "()")
2146       0 ,c-doc-markup-face-name prepend nil)
2147      (,(concat header "\\(" "@" symbol "\\):")
2148       1 ,c-doc-markup-face-name prepend nil)
2149      (,(concat "[#%]" symbol)
2150       0 ,c-doc-markup-face-name prepend nil))
2151    ))
2152
2153(defconst gtkdoc-font-lock-doc-protection
2154  `(("< \\(public\\|private\\|protected\\) >"
2155     1 ,c-doc-markup-face-name prepend nil)))
2156
2157(defconst gtkdoc-font-lock-keywords
2158  `((,(lambda (limit)
2159	(c-font-lock-doc-comments "/\\*\\*$" limit
2160	  gtkdoc-font-lock-doc-comments)
2161	(c-font-lock-doc-comments "/\\*< " limit
2162	  gtkdoc-font-lock-doc-protection)
2163	))))
2164
2165;; Javadoc.
2166
2167(defconst javadoc-font-lock-doc-comments
2168  `(("{@[a-z]+[^}\n\r]*}"		; "{@foo ...}" markup.
2169     0 ,c-doc-markup-face-name prepend nil)
2170    ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup.
2171     3 ,c-doc-markup-face-name prepend nil)
2172    (,(concat "</?\\sw"			; HTML tags.
2173	      "\\("
2174	      (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"
2175		      "\"[^\"]*\"\\|'[^']*'")
2176	      "\\)*>")
2177     0 ,c-doc-markup-face-name prepend nil)
2178    ("&\\(\\sw\\|[.:]\\)+;"		; HTML entities.
2179     0 ,c-doc-markup-face-name prepend nil)
2180    ;; Fontify remaining markup characters as invalid.  Note
2181    ;; that the Javadoc spec is hazy about when "@" is
2182    ;; allowed in non-markup use.
2183    (,(lambda (limit)
2184	(c-find-invalid-doc-markup "[<>&]\\|{@" limit))
2185     0 'font-lock-warning-face prepend nil)))
2186
2187(defconst javadoc-font-lock-keywords
2188  `((,(lambda (limit)
2189	(c-font-lock-doc-comments "/\\*\\*" limit
2190	  javadoc-font-lock-doc-comments)))))
2191
2192;; Pike autodoc.
2193
2194(defconst autodoc-decl-keywords
2195  ;; Adorned regexp matching the keywords that introduce declarations
2196  ;; in Pike Autodoc.
2197  (cc-eval-when-compile
2198    (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode)))
2199
2200(defconst autodoc-decl-type-keywords
2201  ;; Adorned regexp matching the keywords that are followed by a type.
2202  (cc-eval-when-compile
2203    (c-make-keywords-re t '("@elem" "@member") 'pike-mode)))
2204
2205(defun autodoc-font-lock-line-markup (limit)
2206  ;; Fontify all line oriented keywords between the point and LIMIT.
2207  ;; Nil is always returned.
2208  ;;
2209  ;; This function might do hidden buffer changes.
2210
2211  (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("
2212			 c-current-comment-prefix
2213			 "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)"))
2214	(markup-faces (list c-doc-markup-face-name c-doc-face-name)))
2215
2216    (while (re-search-forward line-re limit t)
2217      (goto-char (match-end 1))
2218
2219      (if (looking-at autodoc-decl-keywords)
2220	  (let* ((kwd-pos (point))
2221		 (start (match-end 1))
2222		 (pos start)
2223		 end)
2224
2225	    (c-put-font-lock-face (point) pos markup-faces)
2226
2227	    ;; Put a declaration end mark at the markup keyword and
2228	    ;; remove the faces from the rest of the line so that it
2229	    ;; gets refontified as a declaration later on by
2230	    ;; `c-font-lock-declarations'.
2231	    (c-put-char-property (1- pos) 'c-type 'c-decl-end)
2232	    (goto-char pos)
2233	    (while (progn
2234		     (end-of-line)
2235		     (setq end (point))
2236		     (and (eq (char-before) ?@)
2237			  (not (eobp))
2238			  (progn (forward-char)
2239				 (skip-syntax-forward " ")
2240				 (looking-at c-current-comment-prefix))))
2241	      (goto-char (match-end 0))
2242	      (c-remove-font-lock-face pos (1- end))
2243	      (c-put-font-lock-face (1- end) end markup-faces)
2244	      (setq pos (point)))
2245
2246	    ;; Include the final newline in the removed area.  This
2247	    ;; has no visual effect but it avoids some tricky special
2248	    ;; cases in the testsuite wrt the differences in string
2249	    ;; fontification in Emacs vs XEmacs.
2250	    (c-remove-font-lock-face pos (min (1+ (point)) (point-max)))
2251
2252	    ;; Must handle string literals explicitly inside the declaration.
2253	    (goto-char start)
2254	    (while (re-search-forward
2255		    "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'"
2256		    end 'move)
2257	      (c-put-font-lock-string-face (match-beginning 0)
2258					   (point)))
2259
2260	    ;; Fontify types after keywords that always are followed
2261	    ;; by them.
2262	    (goto-char kwd-pos)
2263	    (when (looking-at autodoc-decl-type-keywords)
2264	      (c-fontify-types-and-refs ((c-promote-possible-types t))
2265		(goto-char start)
2266		(c-forward-syntactic-ws)
2267		(c-forward-type))))
2268
2269	;; Mark each whole line as markup, as long as the logical line
2270	;; continues.
2271	(while (progn
2272		 (c-put-font-lock-face (point)
2273				       (progn (end-of-line) (point))
2274				       markup-faces)
2275		 (and (eq (char-before) ?@)
2276		      (not (eobp))
2277		      (progn (forward-char)
2278			     (skip-syntax-forward " ")
2279			     (looking-at c-current-comment-prefix))))
2280	  (goto-char (match-end 0))))))
2281
2282  nil)
2283
2284(defconst autodoc-font-lock-doc-comments
2285  `(("@\\(\\w+{\\|\\[\\([^\]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)"
2286     ;; In-text markup.
2287     0 ,c-doc-markup-face-name prepend nil)
2288    (autodoc-font-lock-line-markup)
2289    ;; Fontify remaining markup characters as invalid.
2290    (,(lambda (limit)
2291	(c-find-invalid-doc-markup "@" limit))
2292     0 'font-lock-warning-face prepend nil)
2293    ))
2294
2295(defun autodoc-font-lock-keywords ()
2296  ;; Note that we depend on that `c-current-comment-prefix' has got
2297  ;; its proper value here.
2298  ;;
2299  ;; This function might do hidden buffer changes.
2300
2301  ;; The `c-type' text property with `c-decl-end' is used to mark the
2302  ;; end of the `autodoc-decl-keywords' occurrences to fontify the
2303  ;; following declarations.
2304  (setq c-type-decl-end-used t)
2305
2306  `((,(lambda (limit)
2307	(c-font-lock-doc-comments "/[*/]!" limit
2308	  autodoc-font-lock-doc-comments)))))
2309
2310
2311;; 2006-07-10:  awk-font-lock-keywords has been moved back to cc-awk.el.
2312(cc-provide 'cc-fonts)
2313
2314;;; arch-tag: 2f65f405-735f-4da5-8d4b-b957844c5203
2315;;; cc-fonts.el ends here
2316