# HG changeset patch # User Alan Mackenzie # Date 1286654308 0 # Node ID fb9b207b7488a3b80e5706726f40f1fbd0731af5 # Parent 951b5214e93906dfcc525afbce84a3202376b8ab 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. diff -r 951b5214e939 -r fb9b207b7488 lisp/ChangeLog --- a/lisp/ChangeLog Sat Oct 09 12:39:42 2010 -0700 +++ b/lisp/ChangeLog Sat Oct 09 19:58:28 2010 +0000 @@ -1,3 +1,24 @@ +2010-10-09 Alan Mackenzie + + 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. + 2010-10-09 Lars Magne Ingebrigtsen * ibuffer.el (ibuffer-mode-map): Don't redefine the cursor keys, diff -r 951b5214e939 -r fb9b207b7488 lisp/progmodes/cc-engine.el --- a/lisp/progmodes/cc-engine.el Sat Oct 09 12:39:42 2010 -0700 +++ b/lisp/progmodes/cc-engine.el Sat Oct 09 19:58:28 2010 +0000 @@ -5646,17 +5646,23 @@ (defun c-forward-name () ;; Move forward over a complete name if at the beginning of one, - ;; stopping at the next following token. If the point is not at - ;; something that are recognized as name then it stays put. A name - ;; could be something as simple as "foo" in C or something as + ;; stopping at the next following token. A keyword, as such, + ;; doesn't count as a name. If the point is not at something that + ;; is recognized as a name then it stays put. + ;; + ;; A name could be something as simple as "foo" in C or something as ;; complex as "X::B, BIT_MAX >> b>, ::operator<> :: ;; Z<(a>b)> :: operator const X<&foo>::T Q::G::*volatile const" in C++ (this function is actually little ;; more than a `looking-at' call in all modes except those that, - ;; like C++, have `c-recognize-<>-arglists' set). Return nil if no - ;; name is found, 'template if it's an identifier ending with an - ;; angle bracket arglist, 'operator of it's an operator identifier, - ;; or t if it's some other kind of name. + ;; like C++, have `c-recognize-<>-arglists' set). + ;; + ;; Return + ;; o - nil if no name is found; + ;; o - 'template if it's an identifier ending with an angle bracket + ;; arglist; + ;; o - 'operator of it's an operator identifier; + ;; o - t if it's some other kind of name. ;; ;; This function records identifier ranges on ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if @@ -5808,16 +5814,28 @@ (goto-char pos) res)) -(defun c-forward-type () +(defun c-forward-type (&optional brace-block-too) ;; Move forward over a type spec if at the beginning of one, - ;; stopping at the next following token. Return t if it's a known - ;; type that can't be a name or other expression, 'known if it's an - ;; otherwise known type (according to `*-font-lock-extra-types'), - ;; 'prefix if it's a known prefix of a type, 'found if it's a type - ;; that matches one in `c-found-types', 'maybe if it's an identfier - ;; that might be a type, or nil if it can't be a type (the point - ;; isn't moved then). The point is assumed to be at the beginning - ;; of a token. + ;; stopping at the next following token. The keyword "typedef" + ;; isn't part of a type spec here. + ;; + ;; BRACE-BLOCK-TOO, when non-nil, means move over the brace block in + ;; constructs like "struct foo {...} bar ;" or "struct {...} bar;". + ;; The current (2009-03-10) intention is to convert all uses of + ;; `c-forward-type' to call with this parameter set, then to + ;; eliminate it. + ;; + ;; Return + ;; o - t if it's a known type that can't be a name or other + ;; expression; + ;; o - 'known if it's an otherwise known type (according to + ;; `*-font-lock-extra-types'); + ;; o - 'prefix if it's a known prefix of a type; + ;; o - 'found if it's a type that matches one in `c-found-types'; + ;; o - 'maybe if it's an identfier that might be a type; or + ;; o - nil if it can't be a type (the point isn't moved then). + ;; + ;; The point is assumed to be at the beginning of a token. ;; ;; Note that this function doesn't skip past the brace definition ;; that might be considered part of the type, e.g. @@ -5836,32 +5854,39 @@ ;; Skip leading type modifiers. If any are found we know it's a ;; prefix of a type. - (when c-opt-type-modifier-key + (when c-opt-type-modifier-key ; e.g. "const" "volatile", but NOT "typedef" (while (looking-at c-opt-type-modifier-key) (goto-char (match-end 1)) (c-forward-syntactic-ws) (setq res 'prefix))) (cond - ((looking-at c-type-prefix-key) - ;; Looking at a keyword that prefixes a type identifier, - ;; e.g. "class". + ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT + ; "typedef". (goto-char (match-end 1)) (c-forward-syntactic-ws) (setq pos (point)) - (if (memq (setq name-res (c-forward-name)) '(t template)) - (progn - (when (eq name-res t) - ;; In many languages the name can be used without the - ;; prefix, so we add it to `c-found-types'. - (c-add-type pos (point)) - (when (and c-record-type-identifiers - c-last-identifier-range) - (c-record-type-id c-last-identifier-range))) - (setq res t)) - ;; Invalid syntax. - (goto-char start) - (setq res nil))) + + (setq name-res (c-forward-name)) + (setq res (not (null name-res))) + (when (eq name-res t) + ;; In many languages the name can be used without the + ;; prefix, so we add it to `c-found-types'. + (c-add-type pos (point)) + (when (and c-record-type-identifiers + c-last-identifier-range) + (c-record-type-id c-last-identifier-range))) + (when (and brace-block-too + (memq res '(t nil)) + (eq (char-after) ?\{) + (save-excursion + (c-safe + (progn (c-forward-sexp) + (c-forward-syntactic-ws) + (setq pos (point)))))) + (goto-char pos) + (setq res t)) + (unless res (goto-char start))) ; invalid syntax ((progn (setq pos nil) @@ -5951,14 +5976,13 @@ (setq res nil))))) (when res - ;; Skip trailing type modifiers. If any are found we know it's + ;; Skip trailing type modifiers. If any are found we know it's ;; a type. (when c-opt-type-modifier-key - (while (looking-at c-opt-type-modifier-key) + (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile" (goto-char (match-end 1)) (c-forward-syntactic-ws) (setq res t))) - ;; Step over any type suffix operator. Do not let the existence ;; of these alter the classification of the found type, since ;; these operators typically are allowed in normal expressions @@ -5968,7 +5992,7 @@ (goto-char (match-end 1)) (c-forward-syntactic-ws))) - (when c-opt-type-concat-key + (when c-opt-type-concat-key ; Only/mainly for pike. ;; Look for a trailing operator that concatenates the type ;; with a following one, and if so step past that one through ;; a recursive call. Note that we don't record concatenated @@ -6119,11 +6143,15 @@ ;; car ^ ^ point ;; Foo::Foo (int b) : Base (b) {} ;; car ^ ^ point - ;; - ;; The cdr of the return value is non-nil iff a `c-typedef-decl-kwds' - ;; specifier (e.g. class, struct, enum, typedef) is found in the - ;; declaration, i.e. the declared identifier(s) are types. - ;; + ;; + ;; The cdr of the return value is non-nil when a + ;; `c-typedef-decl-kwds' specifier is found in the declaration. + ;; Specifically it is a dotted pair (A . B) where B is t when a + ;; `c-typedef-kwds' ("typedef") is present, and A is t when some + ;; other `c-typedef-decl-kwds' (e.g. class, struct, enum) + ;; specifier is present. I.e., (some of) the declared + ;; identifier(s) are types. + ;; ;; If a cast is parsed: ;; ;; The point is left at the first token after the closing paren of @@ -6181,9 +6209,11 @@ ;; If `backup-at-type' is nil then the other variables have ;; undefined values. backup-at-type backup-type-start backup-id-start - ;; Set if we've found a specifier that makes the defined - ;; identifier(s) types. + ;; Set if we've found a specifier (apart from "typedef") that makes + ;; the defined identifier(s) types. at-type-decl + ;; Set if we've a "typedef" keyword. + at-typedef ;; Set if we've found a specifier that can start a declaration ;; where there's no type. maybe-typeless @@ -6223,12 +6253,14 @@ ;; Look for a specifier keyword clause. (when (looking-at c-prefix-spec-kwds-re) + (if (looking-at c-typedef-key) + (setq at-typedef t)) (setq kwd-sym (c-keyword-sym (match-string 1))) (save-excursion (c-forward-keyword-clause 1) (setq kwd-clause-end (point)))) - (when (setq found-type (c-forward-type)) + (when (setq found-type (c-forward-type t)) ; brace-block-too ;; Found a known or possible type or a prefix of a known type. (when at-type @@ -6293,6 +6325,8 @@ (setq backup-maybe-typeless t))) (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds) + ;; This test only happens after we've scanned a type. + ;; So, with valid syntax, kwd-sym can't be 'typedef. (setq at-type-decl t)) (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds) (setq maybe-typeless t)) @@ -6892,7 +6926,9 @@ (goto-char type-start) (c-forward-type)))) - (cons id-start at-type-decl)) + (cons id-start + (and (or at-type-decl at-typedef) + (cons at-type-decl at-typedef)))) (t ;; False alarm. Restore the recorded ranges. diff -r 951b5214e939 -r fb9b207b7488 lisp/progmodes/cc-fonts.el --- a/lisp/progmodes/cc-fonts.el Sat Oct 09 12:39:42 2010 -0700 +++ b/lisp/progmodes/cc-fonts.el Sat Oct 09 19:58:28 2010 +0000 @@ -289,7 +289,7 @@ ;; bit of the overhead compared to a real matcher. The main reason ;; is however to pass the real search limit to the anchored ;; matcher(s), since most (if not all) font-lock implementations - ;; arbitrarily limits anchored matchers to the same line, and also + ;; arbitrarily limit anchored matchers to the same line, and also ;; to insulate against various other irritating differences between ;; the different (X)Emacs font-lock packages. ;; @@ -310,7 +310,7 @@ ;; covered by the font-lock context.) ;; Note: Replace `byte-compile' with `eval' to debug the generated - ;; lambda easier. + ;; lambda more easily. (byte-compile `(lambda (limit) (let (;; The font-lock package in Emacs is known to clobber @@ -721,16 +721,26 @@ ;; Clear the list of found types if we start from the start of the ;; buffer, to make it easier to get rid of misspelled types and - ;; variables that has gotten recognized as types in malformed code. + ;; variables that have gotten recognized as types in malformed code. (when (bobp) (c-clear-found-types)) - ;; Clear the c-type char properties in the region to recalculate - ;; them properly. This is necessary e.g. to handle constructs that - ;; might been required as declarations temporarily during editing. - ;; The interesting properties are anyway those put on the closest - ;; token before the region. - (c-clear-char-properties (point) limit 'c-type) + ;; Clear the c-type char properties which mark the region, to recalculate + ;; them properly. The most interesting properties are those put on the + ;; closest token before the region. + (save-excursion + (let ((pos (point))) + (c-backward-syntactic-ws) + (c-clear-char-properties + (if (and (not (bobp)) + (memq (c-get-char-property (1- (point)) 'c-type) + '(c-decl-arg-start + c-decl-end + c-decl-id-start + c-decl-type-start))) + (1- (point)) + pos) + limit 'c-type))) ;; Update `c-state-cache' to the beginning of the region. This will ;; make `c-beginning-of-syntax' go faster when it's used later on, @@ -739,6 +749,8 @@ ;; Check if the fontified region starts inside a declarator list so ;; that `c-font-lock-declarators' should be called at the start. + ;; The declared identifiers are font-locked correctly as types, if + ;; that is what they are. (let ((prop (save-excursion (c-backward-syntactic-ws) (unless (bobp) @@ -831,12 +843,19 @@ nil) (defun c-font-lock-declarators (limit list types) - ;; Assuming the point is at the start of a declarator in a - ;; declaration, fontify it. If LIST is non-nil, fontify also all - ;; following declarators in a comma separated list (e.g. "foo" and - ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is - ;; non-nil, fontify all identifiers as types. Nil is always - ;; returned. + ;; Assuming the point is at the start of a declarator in a declaration, + ;; fontify the identifier it declares. (If TYPES is set, it does this via + ;; the macro `c-fontify-types-and-refs'.) + ;; + ;; If LIST is non-nil, also fontify the ids in any following declarators in + ;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;"); + ;; additionally, mark the commas with c-type property 'c-decl-id-start or + ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. + ;; + ;; If TYPES is non-nil, fontify all identifiers as types. + ;; + ;; Nil is always returned. The function leaves point at the delimiter after + ;; the last declarator it processes. ;; ;; This function might do hidden buffer changes. @@ -848,18 +867,31 @@ c-last-identifier-range (separator-prop (if types 'c-decl-type-start 'c-decl-id-start))) - (while (and + ;; The following `while' fontifies a single declarator id each time round. + ;; It loops only when LIST is non-nil. + (while + ;; Inside the following "condition form", we move forward over the + ;; declarator's identifier up as far as any opening bracket (for array + ;; size) or paren (for parameters of function-type) or brace (for + ;; array/struct initialisation) or "=" or terminating delimiter + ;; (e.g. "," or ";" or "}"). + (and pos (< (point) limit) + ;; The following form moves forward over the declarator's + ;; identifier (and what precedes it), returning t. If there + ;; wasn't one, it returns nil, terminating the `while'. (let (got-identifier) (setq paren-depth 0) - ;; Skip over type decl prefix operators. (Note similar - ;; code in `c-forward-decl-or-cast-1'.) + ;; Skip over type decl prefix operators, one for each iteration + ;; of the while. These are, e.g. "*" in "int *foo" or "(" and + ;; "*" in "int (*foo) (void)" (Note similar code in + ;; `c-forward-decl-or-cast-1'.) (while (and (looking-at c-type-decl-prefix-key) (if (and (c-major-mode-is 'c++-mode) - (match-beginning 2)) - ;; If the second submatch matches in C++ then + (match-beginning 3)) + ;; If the third submatch matches in C++ then ;; we're looking at an identifier that's a ;; prefix only if it specifies a member pointer. (progn @@ -882,7 +914,7 @@ (goto-char (match-end 1))) (c-forward-syntactic-ws)) - ;; If we didn't pass the identifier above already, do it now. + ;; If we haven't passed the identifier already, do it now. (unless got-identifier (setq id-start (point)) (c-forward-name)) @@ -890,12 +922,14 @@ (/= id-end pos)) - ;; Skip out of the parens surrounding the identifier. + ;; Skip out of the parens surrounding the identifier. If closing + ;; parens are missing, this form returns nil. (or (= paren-depth 0) (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) (<= (point) limit) + ;; Skip over any trailing bit, such as "__attribute__". (progn (when (looking-at c-decl-hangon-key) (c-forward-keyword-clause 1)) @@ -936,7 +970,7 @@ id-face))) (goto-char next-pos) - (setq pos nil) + (setq pos nil) ; So as to terminate the enclosing `while' form. (when list ;; Jump past any initializer or function prototype to see if ;; there's a ',' to continue at. @@ -944,11 +978,11 @@ (cond ((eq id-face 'font-lock-function-name-face) ;; Skip a parenthesized initializer (C++) or a function ;; prototype. - (if (c-safe (c-forward-sexp 1) t) + (if (c-safe (c-forward-sexp 1) t) ; over the parameter list. (c-forward-syntactic-ws limit) - (goto-char limit))) + (goto-char limit))) ; unbalanced parens - (got-init + (got-init ; "=" sign OR opening "(", "[", or "{" ;; Skip an initializer expression. If we're at a '=' ;; then accept a brace list directly after it to cope ;; with array initializers. Otherwise stop at braces @@ -956,7 +990,7 @@ (and (if (and (eq got-init ?=) (= (c-forward-token-2 1 nil limit) 0) (looking-at "{")) - (c-safe (c-forward-sexp) t) + (c-safe (c-forward-sexp) t) ; over { .... } t) ;; FIXME: Should look for c-decl-end markers here; ;; we might go far into the following declarations @@ -971,7 +1005,7 @@ (c-put-char-property (point) 'c-type separator-prop) (forward-char) (c-forward-syntactic-ws limit) - (setq pos (point)))))) + (setq pos (point)))))) ; acts to make the `while' form continue. nil) (defconst c-font-lock-maybe-decl-faces @@ -984,27 +1018,29 @@ font-lock-keyword-face)) (defun c-font-lock-declarations (limit) + ;; Fontify all the declarations, casts and labels from the point to LIMIT. + ;; Assumes that strings and comments have been fontified already. + ;; ;; This function will be called from font-lock for a region bounded by POINT ;; and LIMIT, as though it were to identify a keyword for ;; font-lock-keyword-face. It always returns NIL to inhibit this and ;; prevent a repeat invocation. See elisp/lispref page "Search-based ;; Fontification". ;; - ;; Fontify all the declarations, casts and labels from the point to LIMIT. - ;; Assumes that strings and comments have been fontified already. - ;; ;; This function might do hidden buffer changes. ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) (save-restriction - (let (;; The position where `c-find-decl-spots' stopped. + (let (;; The position where `c-find-decl-spots' last stopped. start-pos - ;; 'decl if we're in an arglist containing declarations (but - ;; if `c-recognize-paren-inits' is set it might also be an - ;; initializer arglist), '<> if the arglist is of angle - ;; bracket type, 'arglist if it's some other arglist, or nil - ;; if not in an arglist at all. + ;; o - 'decl if we're in an arglist containing declarations + ;; (but if `c-recognize-paren-inits' is set it might also be + ;; an initializer arglist); + ;; o - '<> if the arglist is of angle bracket type; + ;; o - 'arglist if it's some other arglist; + ;; o - nil, if not in an arglist at all. This includes the + ;; parenthesised condition which follows "if", "while", etc. context ;; The position of the next token after the closing paren of ;; the last detected cast. @@ -1082,57 +1118,106 @@ ;; can't start a declaration. t - ;; Set `context'. Look for "<" for the sake of C++-style template - ;; arglists. - (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<)) + ;; Set `context' and `c-restricted-<>-arglists'. Look for + ;; "<" for the sake of C++-style template arglists. + ;; Ignore "(" when it's part of a control flow construct + ;; (e.g. "for ("). + (let ((type (and (> match-pos (point-min)) + (c-get-char-property (1- match-pos) 'c-type)))) + (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<))) + (setq context nil + c-restricted-<>-arglists nil)) + ;; A control flow expression + ((and (eq (char-before match-pos) ?\() + (save-excursion + (goto-char match-pos) + (backward-char) + (c-backward-token-2) + (looking-at c-block-stmt-2-key))) + (setq context nil + c-restricted-<>-arglists t)) + ;; Near BOB. + ((<= match-pos (point-min)) + (setq context 'arglist + c-restricted-<>-arglists t)) + ;; Got a cached hit in a declaration arglist. + ((eq type 'c-decl-arg-start) + (setq context 'decl + c-restricted-<>-arglists nil)) + ;; Inside an angle bracket arglist. + ((or (eq type 'c-<>-arg-sep) + (eq (char-before match-pos) ?<)) + (setq context '<> + c-restricted-<>-arglists nil)) + ;; Got a cached hit in some other type of arglist. + (type + (setq context 'arglist + c-restricted-<>-arglists t)) + ((if inside-macro + (< match-pos max-type-decl-end-before-token) + (< match-pos max-type-decl-end)) + ;; The point is within the range of a previously + ;; encountered type decl expression, so the arglist + ;; is probably one that contains declarations. + ;; However, if `c-recognize-paren-inits' is set it + ;; might also be an initializer arglist. + (setq context 'decl + c-restricted-<>-arglists nil) + ;; The result of this check is cached with a char + ;; property on the match token, so that we can look + ;; it up again when refontifying single lines in a + ;; multiline declaration. + (c-put-char-property (1- match-pos) + 'c-type 'c-decl-arg-start)) + (t (setq context 'arglist + c-restricted-<>-arglists t)))) - ;; Find out the type of the arglist. - (if (<= match-pos (point-min)) - (setq context 'arglist) - (let ((type (c-get-char-property (1- match-pos) 'c-type))) - (cond ((eq type 'c-decl-arg-start) - ;; Got a cached hit in a declaration arglist. - (setq context 'decl)) - ((or (eq type 'c-<>-arg-sep) - (eq (char-before match-pos) ?<)) - ;; Inside an angle bracket arglist. - (setq context '<>)) - (type - ;; Got a cached hit in some other type of arglist. - (setq context 'arglist)) - ((if inside-macro - (< match-pos max-type-decl-end-before-token) - (< match-pos max-type-decl-end)) - ;; The point is within the range of a previously - ;; encountered type decl expression, so the arglist - ;; is probably one that contains declarations. - ;; However, if `c-recognize-paren-inits' is set it - ;; might also be an initializer arglist. - (setq context 'decl) - ;; The result of this check is cached with a char - ;; property on the match token, so that we can look - ;; it up again when refontifying single lines in a - ;; multiline declaration. - (c-put-char-property (1- match-pos) - 'c-type 'c-decl-arg-start)) - (t - (setq context 'arglist))))) + ;; Check we haven't missed a preceding "typedef". + (when (not (looking-at c-typedef-key)) + (c-backward-syntactic-ws) + (c-backward-token-2) + (or (looking-at c-typedef-key) + (goto-char start-pos))) - (setq context nil)) - - ;; If we're in a normal arglist context we don't want to - ;; recognize commas in nested angle bracket arglists since - ;; those commas could be part of our own arglist. - (setq c-restricted-<>-arglists (and c-recognize-<>-arglists - (eq context 'arglist)) - - ;; Now analyze the construct. - decl-or-cast (c-forward-decl-or-cast-1 + ;; Now analyze the construct. + (setq decl-or-cast (c-forward-decl-or-cast-1 match-pos context last-cast-end)) (if (not decl-or-cast) - ;; False alarm. Return t to go on to the next check. - t + ;; Are we at a declarator? + ;; Try to go back to the declaration to check this. + (let (paren-state bod-res lim encl-pos is-typedef) + (goto-char start-pos) + (save-excursion + (setq lim (and (c-syntactic-skip-backward "^;" nil t) + (point)))) + (save-excursion + (setq bod-res (car (c-beginning-of-decl-1 lim))) + (if (and (eq bod-res 'same) + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\}))) + (c-beginning-of-decl-1 lim)) + ;; We're now putatively at the declaration. + (setq paren-state (c-parse-state)) + ;; At top level or inside a "{"? + (if (or (not (setq encl-pos + (c-most-enclosing-brace paren-state))) + (eq (char-after encl-pos) ?\{)) + (progn + (when (looking-at c-typedef-key) ; "typedef" + (setq is-typedef t) + (goto-char (match-end 0)) + (c-forward-syntactic-ws)) + ;; At a real declaration? + (if (memq (c-forward-type t) '(t known found)) + (progn + (c-font-lock-declarators limit t is-typedef) + nil) + ;; False alarm. Return t to go on to the next check. + (goto-char start-pos) + t)) + t))) (if (eq decl-or-cast 'cast) ;; Save the position after the previous cast so we can feed @@ -1296,7 +1381,7 @@ "Complex font lock matchers for types and declarations. Used on level 3 and higher." - ;; Note: This code in this form dumps a number of funtions into the + ;; Note: This code in this form dumps a number of functions into the ;; resulting constant, `c-matchers-3'. At run time, font lock will call ;; each of them as a "FUNCTION" (see Elisp page "Search-based ;; Fontification"). The font lock region is delimited by POINT and the @@ -1348,7 +1433,7 @@ `(,(concat "\\<\\(" re "\\)\\>") 1 'font-lock-type-face))) - ;; Fontify types preceded by `c-type-prefix-kwds'. + ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct"). ,@(when (c-lang-const c-type-prefix-kwds) `((,(byte-compile `(lambda (limit) @@ -1396,23 +1481,25 @@ ;; override it if it turns out to be an new declaration, but ;; it will be wrong if it's an expression (see the test ;; decls-8.cc). - ,@(when (c-lang-const c-opt-block-decls-with-vars-key) - `((,(c-make-font-lock-search-function - (concat "}" - (c-lang-const c-single-line-syntactic-ws) - "\\(" ; 1 + c-single-line-syntactic-ws-depth - (c-lang-const c-type-decl-prefix-key) - "\\|" - (c-lang-const c-symbol-key) - "\\)") - `((c-font-lock-declarators limit t nil) - (progn - (c-put-char-property (match-beginning 0) 'c-type - 'c-decl-id-start) - (goto-char (match-beginning - ,(1+ (c-lang-const - c-single-line-syntactic-ws-depth))))) - (goto-char (match-end 0))))))) +;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key) +;; `((,(c-make-font-lock-search-function +;; (concat "}" +;; (c-lang-const c-single-line-syntactic-ws) +;; "\\(" ; 1 + c-single-line-syntactic-ws-depth +;; (c-lang-const c-type-decl-prefix-key) +;; "\\|" +;; (c-lang-const c-symbol-key) +;; "\\)") +;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face'; +;; ; `t' would mean `font-lock-function-name-face'. +;; (progn +;; (c-put-char-property (match-beginning 0) 'c-type +;; 'c-decl-id-start) +;; ; 'c-decl-type-start) +;; (goto-char (match-beginning +;; ,(1+ (c-lang-const +;; c-single-line-syntactic-ws-depth))))) +;; (goto-char (match-end 0))))))) ;; Fontify the type in C++ "new" expressions. ,@(when (c-major-mode-is 'c++-mode) @@ -1660,6 +1747,10 @@ ;;; C++. (defun c-font-lock-c++-new (limit) + ;; FIXME!!! Put in a comment about the context of this function's + ;; invocation. I think it's called as an ANCHORED-MATCHER within an + ;; ANCHORED-HIGHLIGHTER. (2007/2/10). + ;; ;; Assuming point is after a "new" word, check that it isn't inside ;; a string or comment, and if so try to fontify the type in the ;; allocation expression. Nil is always returned. diff -r 951b5214e939 -r fb9b207b7488 lisp/progmodes/cc-langs.el --- a/lisp/progmodes/cc-langs.el Sat Oct 09 12:39:42 2010 -0700 +++ b/lisp/progmodes/cc-langs.el Sat Oct 09 19:58:28 2010 +0000 @@ -1565,6 +1565,17 @@ ;; In CORBA PSDL: "strong")) +(c-lang-defconst c-typedef-kwds + "Prefix keyword\(s\) like \"typedef\" which make a type declaration out +of a variable declaration." + t '("typedef") + (awk idl java) nil) + +(c-lang-defconst c-typedef-key + ;; Adorned regexp matching `c-typedef-kwds'. + t (c-make-keywords-re t (c-lang-const c-typedef-kwds))) +(c-lang-defvar c-typedef-key (c-lang-const c-typedef-key)) + (c-lang-defconst c-type-prefix-kwds "Keywords where the following name - if any - is a type name, and where the keyword together with the symbol works as a type in @@ -1731,6 +1742,10 @@ ;; types in IDL since they only can occur in "raises" specs. idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil))) +(c-lang-defconst c-typedef-decl-key + t (c-make-keywords-re t (c-lang-const c-typedef-decl-kwds))) +(c-lang-defvar c-typedef-decl-key (c-lang-const c-typedef-decl-key)) + (c-lang-defconst c-typeless-decl-kwds "Keywords introducing declarations where the \(first) identifier \(declarator) follows directly after the keyword, without any type.