aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2010-10-09 19:58:28 +0000
committerAlan Mackenzie2010-10-09 19:58:28 +0000
commite15f8aaa0eb8ac5455d8b5f7536faf7c2b9acbbc (patch)
tree3611031fc35a4f1effe7afba8ced057d963529f0
parenteef3ab9443a2cef449d08aa8832f96007fc3a36b (diff)
downloademacs-e15f8aaa0eb8ac5455d8b5f7536faf7c2b9acbbc.tar.gz
emacs-e15f8aaa0eb8ac5455d8b5f7536faf7c2b9acbbc.zip
Enhance fontification of declarators to take account of the
presence/absence of "typedef". cc-engine.el (c-forward-type): New &optional param "brace-block-too". (c-forward-decl-or-cast-1): cdr of return value now indicates the presence of either or both of a "struct"-like keyword and "typedef". cc-fonts.el (c-complex-decl-matchers): Remove the heuristic fontification of declarators which follow a "}". (c-font-lock-declarations): Fontify declarators according to the presence/absence of "typedef". cc-langs.el (c-typedef-kwds c-typedef-key): New lang variable for "typedef". (c-typedef-decl-key): New lang variable built from c-typedef-decl-kwds.
-rw-r--r--lisp/ChangeLog21
-rw-r--r--lisp/progmodes/cc-engine.el128
-rw-r--r--lisp/progmodes/cc-fonts.el299
-rw-r--r--lisp/progmodes/cc-langs.el15
4 files changed, 313 insertions, 150 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index bbe3d70242d..c7ebc6014fc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,24 @@
12010-10-09 Alan Mackenzie <acm@muc.de>
2
3 Enhance fontification of declarators to take account of the
4 presence/absence of "typedef".
5
6 * cc-engine.el (c-forward-type): New &optional param
7 "brace-block-too".
8 (c-forward-decl-or-cast-1): cdr of return value now indicates the
9 presence of either or both of a "struct"-like keyword and
10 "typedef".
11
12 * cc-fonts.el (c-complex-decl-matchers): Remove the heuristic
13 fontification of declarators which follow a "}".
14 (c-font-lock-declarations): Fontify declarators according to the
15 presence/absence of "typedef".
16
17 * cc-langs.el (c-typedef-kwds c-typedef-key): New lang variable
18 for "typedef".
19 (c-typedef-decl-key): New lang variable built from
20 c-typedef-decl-kwds.
21
12010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org> 222010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 23
3 * ibuffer.el (ibuffer-mode-map): Don't redefine the cursor keys, 24 * ibuffer.el (ibuffer-mode-map): Don't redefine the cursor keys,
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 2a24bf1ce90..18010407eda 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -5646,17 +5646,23 @@ comment at the start of cc-engine.el for more info."
5646 5646
5647(defun c-forward-name () 5647(defun c-forward-name ()
5648 ;; Move forward over a complete name if at the beginning of one, 5648 ;; Move forward over a complete name if at the beginning of one,
5649 ;; stopping at the next following token. If the point is not at 5649 ;; stopping at the next following token. A keyword, as such,
5650 ;; something that are recognized as name then it stays put. A name 5650 ;; doesn't count as a name. If the point is not at something that
5651 ;; could be something as simple as "foo" in C or something as 5651 ;; is recognized as a name then it stays put.
5652 ;;
5653 ;; A name could be something as simple as "foo" in C or something as
5652 ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> :: 5654 ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> ::
5653 ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short 5655 ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short
5654 ;; int>::*volatile const" in C++ (this function is actually little 5656 ;; int>::*volatile const" in C++ (this function is actually little
5655 ;; more than a `looking-at' call in all modes except those that, 5657 ;; more than a `looking-at' call in all modes except those that,
5656 ;; like C++, have `c-recognize-<>-arglists' set). Return nil if no 5658 ;; like C++, have `c-recognize-<>-arglists' set).
5657 ;; name is found, 'template if it's an identifier ending with an 5659 ;;
5658 ;; angle bracket arglist, 'operator of it's an operator identifier, 5660 ;; Return
5659 ;; or t if it's some other kind of name. 5661 ;; o - nil if no name is found;
5662 ;; o - 'template if it's an identifier ending with an angle bracket
5663 ;; arglist;
5664 ;; o - 'operator of it's an operator identifier;
5665 ;; o - t if it's some other kind of name.
5660 ;; 5666 ;;
5661 ;; This function records identifier ranges on 5667 ;; This function records identifier ranges on
5662 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if 5668 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
@@ -5808,16 +5814,28 @@ comment at the start of cc-engine.el for more info."
5808 (goto-char pos) 5814 (goto-char pos)
5809 res)) 5815 res))
5810 5816
5811(defun c-forward-type () 5817(defun c-forward-type (&optional brace-block-too)
5812 ;; Move forward over a type spec if at the beginning of one, 5818 ;; Move forward over a type spec if at the beginning of one,
5813 ;; stopping at the next following token. Return t if it's a known 5819 ;; stopping at the next following token. The keyword "typedef"
5814 ;; type that can't be a name or other expression, 'known if it's an 5820 ;; isn't part of a type spec here.
5815 ;; otherwise known type (according to `*-font-lock-extra-types'), 5821 ;;
5816 ;; 'prefix if it's a known prefix of a type, 'found if it's a type 5822 ;; BRACE-BLOCK-TOO, when non-nil, means move over the brace block in
5817 ;; that matches one in `c-found-types', 'maybe if it's an identfier 5823 ;; constructs like "struct foo {...} bar ;" or "struct {...} bar;".
5818 ;; that might be a type, or nil if it can't be a type (the point 5824 ;; The current (2009-03-10) intention is to convert all uses of
5819 ;; isn't moved then). The point is assumed to be at the beginning 5825 ;; `c-forward-type' to call with this parameter set, then to
5820 ;; of a token. 5826 ;; eliminate it.
5827 ;;
5828 ;; Return
5829 ;; o - t if it's a known type that can't be a name or other
5830 ;; expression;
5831 ;; o - 'known if it's an otherwise known type (according to
5832 ;; `*-font-lock-extra-types');
5833 ;; o - 'prefix if it's a known prefix of a type;
5834 ;; o - 'found if it's a type that matches one in `c-found-types';
5835 ;; o - 'maybe if it's an identfier that might be a type; or
5836 ;; o - nil if it can't be a type (the point isn't moved then).
5837 ;;
5838 ;; The point is assumed to be at the beginning of a token.
5821 ;; 5839 ;;
5822 ;; Note that this function doesn't skip past the brace definition 5840 ;; Note that this function doesn't skip past the brace definition
5823 ;; that might be considered part of the type, e.g. 5841 ;; that might be considered part of the type, e.g.
@@ -5836,32 +5854,39 @@ comment at the start of cc-engine.el for more info."
5836 5854
5837 ;; Skip leading type modifiers. If any are found we know it's a 5855 ;; Skip leading type modifiers. If any are found we know it's a
5838 ;; prefix of a type. 5856 ;; prefix of a type.
5839 (when c-opt-type-modifier-key 5857 (when c-opt-type-modifier-key ; e.g. "const" "volatile", but NOT "typedef"
5840 (while (looking-at c-opt-type-modifier-key) 5858 (while (looking-at c-opt-type-modifier-key)
5841 (goto-char (match-end 1)) 5859 (goto-char (match-end 1))
5842 (c-forward-syntactic-ws) 5860 (c-forward-syntactic-ws)
5843 (setq res 'prefix))) 5861 (setq res 'prefix)))
5844 5862
5845 (cond 5863 (cond
5846 ((looking-at c-type-prefix-key) 5864 ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
5847 ;; Looking at a keyword that prefixes a type identifier, 5865 ; "typedef".
5848 ;; e.g. "class".
5849 (goto-char (match-end 1)) 5866 (goto-char (match-end 1))
5850 (c-forward-syntactic-ws) 5867 (c-forward-syntactic-ws)
5851 (setq pos (point)) 5868 (setq pos (point))
5852 (if (memq (setq name-res (c-forward-name)) '(t template)) 5869
5853 (progn 5870 (setq name-res (c-forward-name))
5854 (when (eq name-res t) 5871 (setq res (not (null name-res)))
5855 ;; In many languages the name can be used without the 5872 (when (eq name-res t)
5856 ;; prefix, so we add it to `c-found-types'. 5873 ;; In many languages the name can be used without the
5857 (c-add-type pos (point)) 5874 ;; prefix, so we add it to `c-found-types'.
5858 (when (and c-record-type-identifiers 5875 (c-add-type pos (point))
5859 c-last-identifier-range) 5876 (when (and c-record-type-identifiers
5860 (c-record-type-id c-last-identifier-range))) 5877 c-last-identifier-range)
5861 (setq res t)) 5878 (c-record-type-id c-last-identifier-range)))
5862 ;; Invalid syntax. 5879 (when (and brace-block-too
5863 (goto-char start) 5880 (memq res '(t nil))
5864 (setq res nil))) 5881 (eq (char-after) ?\{)
5882 (save-excursion
5883 (c-safe
5884 (progn (c-forward-sexp)
5885 (c-forward-syntactic-ws)
5886 (setq pos (point))))))
5887 (goto-char pos)
5888 (setq res t))
5889 (unless res (goto-char start))) ; invalid syntax
5865 5890
5866 ((progn 5891 ((progn
5867 (setq pos nil) 5892 (setq pos nil)
@@ -5951,14 +5976,13 @@ comment at the start of cc-engine.el for more info."
5951 (setq res nil))))) 5976 (setq res nil)))))
5952 5977
5953 (when res 5978 (when res
5954 ;; Skip trailing type modifiers. If any are found we know it's 5979 ;; Skip trailing type modifiers. If any are found we know it's
5955 ;; a type. 5980 ;; a type.
5956 (when c-opt-type-modifier-key 5981 (when c-opt-type-modifier-key
5957 (while (looking-at c-opt-type-modifier-key) 5982 (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
5958 (goto-char (match-end 1)) 5983 (goto-char (match-end 1))
5959 (c-forward-syntactic-ws) 5984 (c-forward-syntactic-ws)
5960 (setq res t))) 5985 (setq res t)))
5961
5962 ;; Step over any type suffix operator. Do not let the existence 5986 ;; Step over any type suffix operator. Do not let the existence
5963 ;; of these alter the classification of the found type, since 5987 ;; of these alter the classification of the found type, since
5964 ;; these operators typically are allowed in normal expressions 5988 ;; these operators typically are allowed in normal expressions
@@ -5968,7 +5992,7 @@ comment at the start of cc-engine.el for more info."
5968 (goto-char (match-end 1)) 5992 (goto-char (match-end 1))
5969 (c-forward-syntactic-ws))) 5993 (c-forward-syntactic-ws)))
5970 5994
5971 (when c-opt-type-concat-key 5995 (when c-opt-type-concat-key ; Only/mainly for pike.
5972 ;; Look for a trailing operator that concatenates the type 5996 ;; Look for a trailing operator that concatenates the type
5973 ;; with a following one, and if so step past that one through 5997 ;; with a following one, and if so step past that one through
5974 ;; a recursive call. Note that we don't record concatenated 5998 ;; a recursive call. Note that we don't record concatenated
@@ -6119,11 +6143,15 @@ comment at the start of cc-engine.el for more info."
6119 ;; car ^ ^ point 6143 ;; car ^ ^ point
6120 ;; Foo::Foo (int b) : Base (b) {} 6144 ;; Foo::Foo (int b) : Base (b) {}
6121 ;; car ^ ^ point 6145 ;; car ^ ^ point
6122 ;; 6146 ;;
6123 ;; The cdr of the return value is non-nil iff a `c-typedef-decl-kwds' 6147 ;; The cdr of the return value is non-nil when a
6124 ;; specifier (e.g. class, struct, enum, typedef) is found in the 6148 ;; `c-typedef-decl-kwds' specifier is found in the declaration.
6125 ;; declaration, i.e. the declared identifier(s) are types. 6149 ;; Specifically it is a dotted pair (A . B) where B is t when a
6126 ;; 6150 ;; `c-typedef-kwds' ("typedef") is present, and A is t when some
6151 ;; other `c-typedef-decl-kwds' (e.g. class, struct, enum)
6152 ;; specifier is present. I.e., (some of) the declared
6153 ;; identifier(s) are types.
6154 ;;
6127 ;; If a cast is parsed: 6155 ;; If a cast is parsed:
6128 ;; 6156 ;;
6129 ;; The point is left at the first token after the closing paren of 6157 ;; The point is left at the first token after the closing paren of
@@ -6181,9 +6209,11 @@ comment at the start of cc-engine.el for more info."
6181 ;; If `backup-at-type' is nil then the other variables have 6209 ;; If `backup-at-type' is nil then the other variables have
6182 ;; undefined values. 6210 ;; undefined values.
6183 backup-at-type backup-type-start backup-id-start 6211 backup-at-type backup-type-start backup-id-start
6184 ;; Set if we've found a specifier that makes the defined 6212 ;; Set if we've found a specifier (apart from "typedef") that makes
6185 ;; identifier(s) types. 6213 ;; the defined identifier(s) types.
6186 at-type-decl 6214 at-type-decl
6215 ;; Set if we've a "typedef" keyword.
6216 at-typedef
6187 ;; Set if we've found a specifier that can start a declaration 6217 ;; Set if we've found a specifier that can start a declaration
6188 ;; where there's no type. 6218 ;; where there's no type.
6189 maybe-typeless 6219 maybe-typeless
@@ -6223,12 +6253,14 @@ comment at the start of cc-engine.el for more info."
6223 6253
6224 ;; Look for a specifier keyword clause. 6254 ;; Look for a specifier keyword clause.
6225 (when (looking-at c-prefix-spec-kwds-re) 6255 (when (looking-at c-prefix-spec-kwds-re)
6256 (if (looking-at c-typedef-key)
6257 (setq at-typedef t))
6226 (setq kwd-sym (c-keyword-sym (match-string 1))) 6258 (setq kwd-sym (c-keyword-sym (match-string 1)))
6227 (save-excursion 6259 (save-excursion
6228 (c-forward-keyword-clause 1) 6260 (c-forward-keyword-clause 1)
6229 (setq kwd-clause-end (point)))) 6261 (setq kwd-clause-end (point))))
6230 6262
6231 (when (setq found-type (c-forward-type)) 6263 (when (setq found-type (c-forward-type t)) ; brace-block-too
6232 ;; Found a known or possible type or a prefix of a known type. 6264 ;; Found a known or possible type or a prefix of a known type.
6233 6265
6234 (when at-type 6266 (when at-type
@@ -6293,6 +6325,8 @@ comment at the start of cc-engine.el for more info."
6293 (setq backup-maybe-typeless t))) 6325 (setq backup-maybe-typeless t)))
6294 6326
6295 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds) 6327 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
6328 ;; This test only happens after we've scanned a type.
6329 ;; So, with valid syntax, kwd-sym can't be 'typedef.
6296 (setq at-type-decl t)) 6330 (setq at-type-decl t))
6297 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds) 6331 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
6298 (setq maybe-typeless t)) 6332 (setq maybe-typeless t))
@@ -6892,7 +6926,9 @@ comment at the start of cc-engine.el for more info."
6892 (goto-char type-start) 6926 (goto-char type-start)
6893 (c-forward-type)))) 6927 (c-forward-type))))
6894 6928
6895 (cons id-start at-type-decl)) 6929 (cons id-start
6930 (and (or at-type-decl at-typedef)
6931 (cons at-type-decl at-typedef))))
6896 6932
6897 (t 6933 (t
6898 ;; False alarm. Restore the recorded ranges. 6934 ;; False alarm. Restore the recorded ranges.
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 72703b9a5e4..a99876a6bfc 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -289,7 +289,7 @@
289 ;; bit of the overhead compared to a real matcher. The main reason 289 ;; bit of the overhead compared to a real matcher. The main reason
290 ;; is however to pass the real search limit to the anchored 290 ;; is however to pass the real search limit to the anchored
291 ;; matcher(s), since most (if not all) font-lock implementations 291 ;; matcher(s), since most (if not all) font-lock implementations
292 ;; arbitrarily limits anchored matchers to the same line, and also 292 ;; arbitrarily limit anchored matchers to the same line, and also
293 ;; to insulate against various other irritating differences between 293 ;; to insulate against various other irritating differences between
294 ;; the different (X)Emacs font-lock packages. 294 ;; the different (X)Emacs font-lock packages.
295 ;; 295 ;;
@@ -310,7 +310,7 @@
310 ;; covered by the font-lock context.) 310 ;; covered by the font-lock context.)
311 311
312 ;; Note: Replace `byte-compile' with `eval' to debug the generated 312 ;; Note: Replace `byte-compile' with `eval' to debug the generated
313 ;; lambda easier. 313 ;; lambda more easily.
314 (byte-compile 314 (byte-compile
315 `(lambda (limit) 315 `(lambda (limit)
316 (let (;; The font-lock package in Emacs is known to clobber 316 (let (;; The font-lock package in Emacs is known to clobber
@@ -721,16 +721,26 @@ casts and declarations are fontified. Used on level 2 and higher."
721 721
722 ;; Clear the list of found types if we start from the start of the 722 ;; Clear the list of found types if we start from the start of the
723 ;; buffer, to make it easier to get rid of misspelled types and 723 ;; buffer, to make it easier to get rid of misspelled types and
724 ;; variables that has gotten recognized as types in malformed code. 724 ;; variables that have gotten recognized as types in malformed code.
725 (when (bobp) 725 (when (bobp)
726 (c-clear-found-types)) 726 (c-clear-found-types))
727 727
728 ;; Clear the c-type char properties in the region to recalculate 728 ;; Clear the c-type char properties which mark the region, to recalculate
729 ;; them properly. This is necessary e.g. to handle constructs that 729 ;; them properly. The most interesting properties are those put on the
730 ;; might been required as declarations temporarily during editing. 730 ;; closest token before the region.
731 ;; The interesting properties are anyway those put on the closest 731 (save-excursion
732 ;; token before the region. 732 (let ((pos (point)))
733 (c-clear-char-properties (point) limit 'c-type) 733 (c-backward-syntactic-ws)
734 (c-clear-char-properties
735 (if (and (not (bobp))
736 (memq (c-get-char-property (1- (point)) 'c-type)
737 '(c-decl-arg-start
738 c-decl-end
739 c-decl-id-start
740 c-decl-type-start)))
741 (1- (point))
742 pos)
743 limit 'c-type)))
734 744
735 ;; Update `c-state-cache' to the beginning of the region. This will 745 ;; Update `c-state-cache' to the beginning of the region. This will
736 ;; make `c-beginning-of-syntax' go faster when it's used later on, 746 ;; make `c-beginning-of-syntax' go faster when it's used later on,
@@ -739,6 +749,8 @@ casts and declarations are fontified. Used on level 2 and higher."
739 749
740 ;; Check if the fontified region starts inside a declarator list so 750 ;; Check if the fontified region starts inside a declarator list so
741 ;; that `c-font-lock-declarators' should be called at the start. 751 ;; that `c-font-lock-declarators' should be called at the start.
752 ;; The declared identifiers are font-locked correctly as types, if
753 ;; that is what they are.
742 (let ((prop (save-excursion 754 (let ((prop (save-excursion
743 (c-backward-syntactic-ws) 755 (c-backward-syntactic-ws)
744 (unless (bobp) 756 (unless (bobp)
@@ -831,12 +843,19 @@ casts and declarations are fontified. Used on level 2 and higher."
831 nil) 843 nil)
832 844
833(defun c-font-lock-declarators (limit list types) 845(defun c-font-lock-declarators (limit list types)
834 ;; Assuming the point is at the start of a declarator in a 846 ;; Assuming the point is at the start of a declarator in a declaration,
835 ;; declaration, fontify it. If LIST is non-nil, fontify also all 847 ;; fontify the identifier it declares. (If TYPES is set, it does this via
836 ;; following declarators in a comma separated list (e.g. "foo" and 848 ;; the macro `c-fontify-types-and-refs'.)
837 ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is 849 ;;
838 ;; non-nil, fontify all identifiers as types. Nil is always 850 ;; If LIST is non-nil, also fontify the ids in any following declarators in
839 ;; returned. 851 ;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;");
852 ;; additionally, mark the commas with c-type property 'c-decl-id-start or
853 ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT.
854 ;;
855 ;; If TYPES is non-nil, fontify all identifiers as types.
856 ;;
857 ;; Nil is always returned. The function leaves point at the delimiter after
858 ;; the last declarator it processes.
840 ;; 859 ;;
841 ;; This function might do hidden buffer changes. 860 ;; This function might do hidden buffer changes.
842 861
@@ -848,18 +867,31 @@ casts and declarations are fontified. Used on level 2 and higher."
848 c-last-identifier-range 867 c-last-identifier-range
849 (separator-prop (if types 'c-decl-type-start 'c-decl-id-start))) 868 (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
850 869
851 (while (and 870 ;; The following `while' fontifies a single declarator id each time round.
871 ;; It loops only when LIST is non-nil.
872 (while
873 ;; Inside the following "condition form", we move forward over the
874 ;; declarator's identifier up as far as any opening bracket (for array
875 ;; size) or paren (for parameters of function-type) or brace (for
876 ;; array/struct initialisation) or "=" or terminating delimiter
877 ;; (e.g. "," or ";" or "}").
878 (and
852 pos 879 pos
853 (< (point) limit) 880 (< (point) limit)
854 881
882 ;; The following form moves forward over the declarator's
883 ;; identifier (and what precedes it), returning t. If there
884 ;; wasn't one, it returns nil, terminating the `while'.
855 (let (got-identifier) 885 (let (got-identifier)
856 (setq paren-depth 0) 886 (setq paren-depth 0)
857 ;; Skip over type decl prefix operators. (Note similar 887 ;; Skip over type decl prefix operators, one for each iteration
858 ;; code in `c-forward-decl-or-cast-1'.) 888 ;; of the while. These are, e.g. "*" in "int *foo" or "(" and
889 ;; "*" in "int (*foo) (void)" (Note similar code in
890 ;; `c-forward-decl-or-cast-1'.)
859 (while (and (looking-at c-type-decl-prefix-key) 891 (while (and (looking-at c-type-decl-prefix-key)
860 (if (and (c-major-mode-is 'c++-mode) 892 (if (and (c-major-mode-is 'c++-mode)
861 (match-beginning 2)) 893 (match-beginning 3))
862 ;; If the second submatch matches in C++ then 894 ;; If the third submatch matches in C++ then
863 ;; we're looking at an identifier that's a 895 ;; we're looking at an identifier that's a
864 ;; prefix only if it specifies a member pointer. 896 ;; prefix only if it specifies a member pointer.
865 (progn 897 (progn
@@ -882,7 +914,7 @@ casts and declarations are fontified. Used on level 2 and higher."
882 (goto-char (match-end 1))) 914 (goto-char (match-end 1)))
883 (c-forward-syntactic-ws)) 915 (c-forward-syntactic-ws))
884 916
885 ;; If we didn't pass the identifier above already, do it now. 917 ;; If we haven't passed the identifier already, do it now.
886 (unless got-identifier 918 (unless got-identifier
887 (setq id-start (point)) 919 (setq id-start (point))
888 (c-forward-name)) 920 (c-forward-name))
@@ -890,12 +922,14 @@ casts and declarations are fontified. Used on level 2 and higher."
890 922
891 (/= id-end pos)) 923 (/= id-end pos))
892 924
893 ;; Skip out of the parens surrounding the identifier. 925 ;; Skip out of the parens surrounding the identifier. If closing
926 ;; parens are missing, this form returns nil.
894 (or (= paren-depth 0) 927 (or (= paren-depth 0)
895 (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) 928 (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
896 929
897 (<= (point) limit) 930 (<= (point) limit)
898 931
932 ;; Skip over any trailing bit, such as "__attribute__".
899 (progn 933 (progn
900 (when (looking-at c-decl-hangon-key) 934 (when (looking-at c-decl-hangon-key)
901 (c-forward-keyword-clause 1)) 935 (c-forward-keyword-clause 1))
@@ -936,7 +970,7 @@ casts and declarations are fontified. Used on level 2 and higher."
936 id-face))) 970 id-face)))
937 971
938 (goto-char next-pos) 972 (goto-char next-pos)
939 (setq pos nil) 973 (setq pos nil) ; So as to terminate the enclosing `while' form.
940 (when list 974 (when list
941 ;; Jump past any initializer or function prototype to see if 975 ;; Jump past any initializer or function prototype to see if
942 ;; there's a ',' to continue at. 976 ;; there's a ',' to continue at.
@@ -944,11 +978,11 @@ casts and declarations are fontified. Used on level 2 and higher."
944 (cond ((eq id-face 'font-lock-function-name-face) 978 (cond ((eq id-face 'font-lock-function-name-face)
945 ;; Skip a parenthesized initializer (C++) or a function 979 ;; Skip a parenthesized initializer (C++) or a function
946 ;; prototype. 980 ;; prototype.
947 (if (c-safe (c-forward-sexp 1) t) 981 (if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
948 (c-forward-syntactic-ws limit) 982 (c-forward-syntactic-ws limit)
949 (goto-char limit))) 983 (goto-char limit))) ; unbalanced parens
950 984
951 (got-init 985 (got-init ; "=" sign OR opening "(", "[", or "{"
952 ;; Skip an initializer expression. If we're at a '=' 986 ;; Skip an initializer expression. If we're at a '='
953 ;; then accept a brace list directly after it to cope 987 ;; then accept a brace list directly after it to cope
954 ;; with array initializers. Otherwise stop at braces 988 ;; with array initializers. Otherwise stop at braces
@@ -956,7 +990,7 @@ casts and declarations are fontified. Used on level 2 and higher."
956 (and (if (and (eq got-init ?=) 990 (and (if (and (eq got-init ?=)
957 (= (c-forward-token-2 1 nil limit) 0) 991 (= (c-forward-token-2 1 nil limit) 0)
958 (looking-at "{")) 992 (looking-at "{"))
959 (c-safe (c-forward-sexp) t) 993 (c-safe (c-forward-sexp) t) ; over { .... }
960 t) 994 t)
961 ;; FIXME: Should look for c-decl-end markers here; 995 ;; FIXME: Should look for c-decl-end markers here;
962 ;; we might go far into the following declarations 996 ;; we might go far into the following declarations
@@ -971,7 +1005,7 @@ casts and declarations are fontified. Used on level 2 and higher."
971 (c-put-char-property (point) 'c-type separator-prop) 1005 (c-put-char-property (point) 'c-type separator-prop)
972 (forward-char) 1006 (forward-char)
973 (c-forward-syntactic-ws limit) 1007 (c-forward-syntactic-ws limit)
974 (setq pos (point)))))) 1008 (setq pos (point)))))) ; acts to make the `while' form continue.
975 nil) 1009 nil)
976 1010
977(defconst c-font-lock-maybe-decl-faces 1011(defconst c-font-lock-maybe-decl-faces
@@ -984,27 +1018,29 @@ casts and declarations are fontified. Used on level 2 and higher."
984 font-lock-keyword-face)) 1018 font-lock-keyword-face))
985 1019
986(defun c-font-lock-declarations (limit) 1020(defun c-font-lock-declarations (limit)
1021 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
1022 ;; Assumes that strings and comments have been fontified already.
1023 ;;
987 ;; This function will be called from font-lock for a region bounded by POINT 1024 ;; This function will be called from font-lock for a region bounded by POINT
988 ;; and LIMIT, as though it were to identify a keyword for 1025 ;; and LIMIT, as though it were to identify a keyword for
989 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1026 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
990 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1027 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
991 ;; Fontification". 1028 ;; Fontification".
992 ;; 1029 ;;
993 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
994 ;; Assumes that strings and comments have been fontified already.
995 ;;
996 ;; This function might do hidden buffer changes. 1030 ;; This function might do hidden buffer changes.
997 1031
998 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) 1032 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
999 1033
1000 (save-restriction 1034 (save-restriction
1001 (let (;; The position where `c-find-decl-spots' stopped. 1035 (let (;; The position where `c-find-decl-spots' last stopped.
1002 start-pos 1036 start-pos
1003 ;; 'decl if we're in an arglist containing declarations (but 1037 ;; o - 'decl if we're in an arglist containing declarations
1004 ;; if `c-recognize-paren-inits' is set it might also be an 1038 ;; (but if `c-recognize-paren-inits' is set it might also be
1005 ;; initializer arglist), '<> if the arglist is of angle 1039 ;; an initializer arglist);
1006 ;; bracket type, 'arglist if it's some other arglist, or nil 1040 ;; o - '<> if the arglist is of angle bracket type;
1007 ;; if not in an arglist at all. 1041 ;; o - 'arglist if it's some other arglist;
1042 ;; o - nil, if not in an arglist at all. This includes the
1043 ;; parenthesised condition which follows "if", "while", etc.
1008 context 1044 context
1009 ;; The position of the next token after the closing paren of 1045 ;; The position of the next token after the closing paren of
1010 ;; the last detected cast. 1046 ;; the last detected cast.
@@ -1082,57 +1118,106 @@ casts and declarations are fontified. Used on level 2 and higher."
1082 ;; can't start a declaration. 1118 ;; can't start a declaration.
1083 t 1119 t
1084 1120
1085 ;; Set `context'. Look for "<" for the sake of C++-style template 1121 ;; Set `context' and `c-restricted-<>-arglists'. Look for
1086 ;; arglists. 1122 ;; "<" for the sake of C++-style template arglists.
1087 (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<)) 1123 ;; Ignore "(" when it's part of a control flow construct
1088 1124 ;; (e.g. "for (").
1089 ;; Find out the type of the arglist. 1125 (let ((type (and (> match-pos (point-min))
1090 (if (<= match-pos (point-min)) 1126 (c-get-char-property (1- match-pos) 'c-type))))
1091 (setq context 'arglist) 1127 (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
1092 (let ((type (c-get-char-property (1- match-pos) 'c-type))) 1128 (setq context nil
1093 (cond ((eq type 'c-decl-arg-start) 1129 c-restricted-<>-arglists nil))
1094 ;; Got a cached hit in a declaration arglist. 1130 ;; A control flow expression
1095 (setq context 'decl)) 1131 ((and (eq (char-before match-pos) ?\()
1096 ((or (eq type 'c-<>-arg-sep) 1132 (save-excursion
1097 (eq (char-before match-pos) ?<)) 1133 (goto-char match-pos)
1098 ;; Inside an angle bracket arglist. 1134 (backward-char)
1099 (setq context '<>)) 1135 (c-backward-token-2)
1100 (type 1136 (looking-at c-block-stmt-2-key)))
1101 ;; Got a cached hit in some other type of arglist. 1137 (setq context nil
1102 (setq context 'arglist)) 1138 c-restricted-<>-arglists t))
1103 ((if inside-macro 1139 ;; Near BOB.
1104 (< match-pos max-type-decl-end-before-token) 1140 ((<= match-pos (point-min))
1105 (< match-pos max-type-decl-end)) 1141 (setq context 'arglist
1106 ;; The point is within the range of a previously 1142 c-restricted-<>-arglists t))
1107 ;; encountered type decl expression, so the arglist 1143 ;; Got a cached hit in a declaration arglist.
1108 ;; is probably one that contains declarations. 1144 ((eq type 'c-decl-arg-start)
1109 ;; However, if `c-recognize-paren-inits' is set it 1145 (setq context 'decl
1110 ;; might also be an initializer arglist. 1146 c-restricted-<>-arglists nil))
1111 (setq context 'decl) 1147 ;; Inside an angle bracket arglist.
1112 ;; The result of this check is cached with a char 1148 ((or (eq type 'c-<>-arg-sep)
1113 ;; property on the match token, so that we can look 1149 (eq (char-before match-pos) ?<))
1114 ;; it up again when refontifying single lines in a 1150 (setq context '<>
1115 ;; multiline declaration. 1151 c-restricted-<>-arglists nil))
1116 (c-put-char-property (1- match-pos) 1152 ;; Got a cached hit in some other type of arglist.
1117 'c-type 'c-decl-arg-start)) 1153 (type
1118 (t 1154 (setq context 'arglist
1119 (setq context 'arglist))))) 1155 c-restricted-<>-arglists t))
1120 1156 ((if inside-macro
1121 (setq context nil)) 1157 (< match-pos max-type-decl-end-before-token)
1122 1158 (< match-pos max-type-decl-end))
1123 ;; If we're in a normal arglist context we don't want to 1159 ;; The point is within the range of a previously
1124 ;; recognize commas in nested angle bracket arglists since 1160 ;; encountered type decl expression, so the arglist
1125 ;; those commas could be part of our own arglist. 1161 ;; is probably one that contains declarations.
1126 (setq c-restricted-<>-arglists (and c-recognize-<>-arglists 1162 ;; However, if `c-recognize-paren-inits' is set it
1127 (eq context 'arglist)) 1163 ;; might also be an initializer arglist.
1128 1164 (setq context 'decl
1129 ;; Now analyze the construct. 1165 c-restricted-<>-arglists nil)
1130 decl-or-cast (c-forward-decl-or-cast-1 1166 ;; The result of this check is cached with a char
1167 ;; property on the match token, so that we can look
1168 ;; it up again when refontifying single lines in a
1169 ;; multiline declaration.
1170 (c-put-char-property (1- match-pos)
1171 'c-type 'c-decl-arg-start))
1172 (t (setq context 'arglist
1173 c-restricted-<>-arglists t))))
1174
1175 ;; Check we haven't missed a preceding "typedef".
1176 (when (not (looking-at c-typedef-key))
1177 (c-backward-syntactic-ws)
1178 (c-backward-token-2)
1179 (or (looking-at c-typedef-key)
1180 (goto-char start-pos)))
1181
1182 ;; Now analyze the construct.
1183 (setq decl-or-cast (c-forward-decl-or-cast-1
1131 match-pos context last-cast-end)) 1184 match-pos context last-cast-end))
1132 1185
1133 (if (not decl-or-cast) 1186 (if (not decl-or-cast)
1134 ;; False alarm. Return t to go on to the next check. 1187 ;; Are we at a declarator?
1135 t 1188 ;; Try to go back to the declaration to check this.
1189 (let (paren-state bod-res lim encl-pos is-typedef)
1190 (goto-char start-pos)
1191 (save-excursion
1192 (setq lim (and (c-syntactic-skip-backward "^;" nil t)
1193 (point))))
1194 (save-excursion
1195 (setq bod-res (car (c-beginning-of-decl-1 lim)))
1196 (if (and (eq bod-res 'same)
1197 (progn
1198 (c-backward-syntactic-ws)
1199 (eq (char-before) ?\})))
1200 (c-beginning-of-decl-1 lim))
1201 ;; We're now putatively at the declaration.
1202 (setq paren-state (c-parse-state))
1203 ;; At top level or inside a "{"?
1204 (if (or (not (setq encl-pos
1205 (c-most-enclosing-brace paren-state)))
1206 (eq (char-after encl-pos) ?\{))
1207 (progn
1208 (when (looking-at c-typedef-key) ; "typedef"
1209 (setq is-typedef t)
1210 (goto-char (match-end 0))
1211 (c-forward-syntactic-ws))
1212 ;; At a real declaration?
1213 (if (memq (c-forward-type t) '(t known found))
1214 (progn
1215 (c-font-lock-declarators limit t is-typedef)
1216 nil)
1217 ;; False alarm. Return t to go on to the next check.
1218 (goto-char start-pos)
1219 t))
1220 t)))
1136 1221
1137 (if (eq decl-or-cast 'cast) 1222 (if (eq decl-or-cast 'cast)
1138 ;; Save the position after the previous cast so we can feed 1223 ;; Save the position after the previous cast so we can feed
@@ -1296,7 +1381,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1296 "Complex font lock matchers for types and declarations. Used on level 1381 "Complex font lock matchers for types and declarations. Used on level
12973 and higher." 13823 and higher."
1298 1383
1299 ;; Note: This code in this form dumps a number of funtions into the 1384 ;; Note: This code in this form dumps a number of functions into the
1300 ;; resulting constant, `c-matchers-3'. At run time, font lock will call 1385 ;; resulting constant, `c-matchers-3'. At run time, font lock will call
1301 ;; each of them as a "FUNCTION" (see Elisp page "Search-based 1386 ;; each of them as a "FUNCTION" (see Elisp page "Search-based
1302 ;; Fontification"). The font lock region is delimited by POINT and the 1387 ;; Fontification"). The font lock region is delimited by POINT and the
@@ -1348,7 +1433,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1348 `(,(concat "\\<\\(" re "\\)\\>") 1433 `(,(concat "\\<\\(" re "\\)\\>")
1349 1 'font-lock-type-face))) 1434 1 'font-lock-type-face)))
1350 1435
1351 ;; Fontify types preceded by `c-type-prefix-kwds'. 1436 ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct").
1352 ,@(when (c-lang-const c-type-prefix-kwds) 1437 ,@(when (c-lang-const c-type-prefix-kwds)
1353 `((,(byte-compile 1438 `((,(byte-compile
1354 `(lambda (limit) 1439 `(lambda (limit)
@@ -1396,23 +1481,25 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1396 ;; override it if it turns out to be an new declaration, but 1481 ;; override it if it turns out to be an new declaration, but
1397 ;; it will be wrong if it's an expression (see the test 1482 ;; it will be wrong if it's an expression (see the test
1398 ;; decls-8.cc). 1483 ;; decls-8.cc).
1399 ,@(when (c-lang-const c-opt-block-decls-with-vars-key) 1484;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
1400 `((,(c-make-font-lock-search-function 1485;; `((,(c-make-font-lock-search-function
1401 (concat "}" 1486;; (concat "}"
1402 (c-lang-const c-single-line-syntactic-ws) 1487;; (c-lang-const c-single-line-syntactic-ws)
1403 "\\(" ; 1 + c-single-line-syntactic-ws-depth 1488;; "\\(" ; 1 + c-single-line-syntactic-ws-depth
1404 (c-lang-const c-type-decl-prefix-key) 1489;; (c-lang-const c-type-decl-prefix-key)
1405 "\\|" 1490;; "\\|"
1406 (c-lang-const c-symbol-key) 1491;; (c-lang-const c-symbol-key)
1407 "\\)") 1492;; "\\)")
1408 `((c-font-lock-declarators limit t nil) 1493;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face';
1409 (progn 1494;; ; `t' would mean `font-lock-function-name-face'.
1410 (c-put-char-property (match-beginning 0) 'c-type 1495;; (progn
1411 'c-decl-id-start) 1496;; (c-put-char-property (match-beginning 0) 'c-type
1412 (goto-char (match-beginning 1497;; 'c-decl-id-start)
1413 ,(1+ (c-lang-const 1498;; ; 'c-decl-type-start)
1414 c-single-line-syntactic-ws-depth))))) 1499;; (goto-char (match-beginning
1415 (goto-char (match-end 0))))))) 1500;; ,(1+ (c-lang-const
1501;; c-single-line-syntactic-ws-depth)))))
1502;; (goto-char (match-end 0)))))))
1416 1503
1417 ;; Fontify the type in C++ "new" expressions. 1504 ;; Fontify the type in C++ "new" expressions.
1418 ,@(when (c-major-mode-is 'c++-mode) 1505 ,@(when (c-major-mode-is 'c++-mode)
@@ -1660,6 +1747,10 @@ need for `c-font-lock-extra-types'.")
1660;;; C++. 1747;;; C++.
1661 1748
1662(defun c-font-lock-c++-new (limit) 1749(defun c-font-lock-c++-new (limit)
1750 ;; FIXME!!! Put in a comment about the context of this function's
1751 ;; invocation. I think it's called as an ANCHORED-MATCHER within an
1752 ;; ANCHORED-HIGHLIGHTER. (2007/2/10).
1753 ;;
1663 ;; Assuming point is after a "new" word, check that it isn't inside 1754 ;; Assuming point is after a "new" word, check that it isn't inside
1664 ;; a string or comment, and if so try to fontify the type in the 1755 ;; a string or comment, and if so try to fontify the type in the
1665 ;; allocation expression. Nil is always returned. 1756 ;; allocation expression. Nil is always returned.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 5cd5c0b95ca..ba056133651 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1565,6 +1565,17 @@ be a subset of `c-primitive-type-kwds'."
1565 ;; In CORBA PSDL: 1565 ;; In CORBA PSDL:
1566 "strong")) 1566 "strong"))
1567 1567
1568(c-lang-defconst c-typedef-kwds
1569 "Prefix keyword\(s\) like \"typedef\" which make a type declaration out
1570of a variable declaration."
1571 t '("typedef")
1572 (awk idl java) nil)
1573
1574(c-lang-defconst c-typedef-key
1575 ;; Adorned regexp matching `c-typedef-kwds'.
1576 t (c-make-keywords-re t (c-lang-const c-typedef-kwds)))
1577(c-lang-defvar c-typedef-key (c-lang-const c-typedef-key))
1578
1568(c-lang-defconst c-type-prefix-kwds 1579(c-lang-defconst c-type-prefix-kwds
1569 "Keywords where the following name - if any - is a type name, and 1580 "Keywords where the following name - if any - is a type name, and
1570where the keyword together with the symbol works as a type in 1581where the keyword together with the symbol works as a type in
@@ -1731,6 +1742,10 @@ will be handled."
1731 ;; types in IDL since they only can occur in "raises" specs. 1742 ;; types in IDL since they only can occur in "raises" specs.
1732 idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil))) 1743 idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
1733 1744
1745(c-lang-defconst c-typedef-decl-key
1746 t (c-make-keywords-re t (c-lang-const c-typedef-decl-kwds)))
1747(c-lang-defvar c-typedef-decl-key (c-lang-const c-typedef-decl-key))
1748
1734(c-lang-defconst c-typeless-decl-kwds 1749(c-lang-defconst c-typeless-decl-kwds
1735 "Keywords introducing declarations where the \(first) identifier 1750 "Keywords introducing declarations where the \(first) identifier
1736\(declarator) follows directly after the keyword, without any type. 1751\(declarator) follows directly after the keyword, without any type.