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