summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2022-11-17 10:34:41 +0000
committerAlan Mackenzie <acm@muc.de>2022-11-17 10:36:59 +0000
commitca3cc92e14a6bdaf6fb817fff9e633f30d461359 (patch)
tree81248fd8333c83d08eec5d655bf3c8dbfd82bfd1 /lisp
parent5df1fd19baddb811ab358b6f1358d4b6fad434a2 (diff)
downloademacs-ca3cc92e14a6bdaf6fb817fff9e633f30d461359.tar.gz
emacs-ca3cc92e14a6bdaf6fb817fff9e633f30d461359.tar.bz2
emacs-ca3cc92e14a6bdaf6fb817fff9e633f30d461359.zip
CC Mode: Make implicit int types following specifiers fontify correctly
This fixes bug #59267. It applies to C Mode only, and refers to constructs like "register count;" which are implicitly of int type. * lisp/progmodes/cc-engine.el (c-forward-type): Use the new regexp c-maybe-typeless-specifier-re in place of c-opt-type-modifier-prefix-key. Add an extra arm to the main cond form to handle the construct, and another to handle "extern "C" foo_t my_foo;". (c-forward-decl-or-cast-1): Adapt to handle the result no-id from c-forward-type. * lisp/progmodes/cc-langs.el (c-maybe-typeless-specifier-re): New lang const/var.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/cc-engine.el44
-rw-r--r--lisp/progmodes/cc-langs.el8
2 files changed, 42 insertions, 10 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index df8387905f6..8813ec4686b 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -9036,7 +9036,8 @@ multi-line strings (but not C++, for example)."
;; o - 'found if it's a type that matches one in `c-found-types';
;; o - 'maybe if it's an identifier that might be a type;
;; o - 'decltype if it's a decltype(variable) declaration; - or
- ;; o - 'no-id if "auto" precluded parsing a type identifier.
+ ;; o - 'no-id if "auto" precluded parsing a type identifier (C++)
+ ;; or the type int was implicit (C).
;; 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.
@@ -9060,10 +9061,11 @@ multi-line strings (but not C++, for example)."
;; Skip leading type modifiers. If any are found we know it's a
;; prefix of a type.
- (when c-opt-type-modifier-prefix-key ; e.g. "const" "volatile", but NOT "typedef"
- (while (looking-at c-opt-type-modifier-prefix-key)
- (when (looking-at c-no-type-key)
- (setq res 'no-id))
+ (when c-maybe-typeless-specifier-re
+ (while (looking-at c-maybe-typeless-specifier-re)
+ (save-match-data
+ (when (looking-at c-no-type-key)
+ (setq res 'no-id)))
(goto-char (match-end 1))
(c-forward-syntactic-ws)
(or (eq res 'no-id)
@@ -9128,6 +9130,9 @@ multi-line strings (but not C++, for example)."
(not (eq res 'no-id))
(progn
(setq pos nil)
+ (while (and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))
(if (looking-at c-identifier-start)
(save-excursion
(setq id-start (point)
@@ -9187,6 +9192,18 @@ multi-line strings (but not C++, for example)."
(goto-char (match-end 1))
(c-forward-syntactic-ws)))))
+ ((and (eq name-res t)
+ (eq res 'prefix)
+ (c-major-mode-is 'c-mode)
+ (save-excursion
+ (goto-char id-end)
+ (and (not (looking-at c-symbol-start))
+ (not (looking-at c-type-decl-prefix-key)))))
+ ;; A C specifier followed by an implicit int, e.g.
+ ;; "register count;"
+ (goto-char id-start)
+ (setq res 'no-id))
+
(name-res
(cond ((eq name-res t)
;; A normal identifier.
@@ -9224,7 +9241,11 @@ multi-line strings (but not C++, for example)."
(t
;; Otherwise it's an operator identifier, which is not a type.
(goto-char start)
- (setq res nil)))))
+ (setq res nil))))
+
+ ((eq res 'prefix)
+ ;; Deal with "extern "C" foo_t my_foo;"
+ (setq res nil)))
(when (not (memq res '(nil no-id)))
;; Skip trailing type modifiers. If any are found we know it's
@@ -10012,9 +10033,11 @@ This function might do hidden buffer changes."
got-suffix-after-parens id-start
paren-depth 0))
- (if (setq at-type (if (eq backup-at-type 'prefix)
- t
- backup-at-type))
+ (if (not (memq
+ (setq at-type (if (eq backup-at-type 'prefix)
+ t
+ backup-at-type))
+ '(nil no-id)))
(setq type-start backup-type-start
id-start backup-id-start)
(setq type-start start-pos
@@ -11219,7 +11242,8 @@ This function might do hidden buffer changes."
;; Record the type's coordinates in `c-record-type-identifiers' for
;; later fontification.
- (when (and c-record-type-identifiers at-type ;; (not (eq at-type t))
+ (when (and c-record-type-identifiers
+ (not (memq at-type '(nil no-id)))
;; There seems no reason to exclude a token from
;; fontification just because it's "a known type that can't
;; be a name or other expression". 2013-09-18.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 291af038b79..94c84a6a702 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -3869,6 +3869,14 @@ possible for good performance."
t)
"\\>")))
+(c-lang-defconst c-maybe-typeless-specifier-re
+ "Regexp matching keywords which might, but needn't, declare variables with
+no explicit type given, or nil in languages without such specifiers."
+ t (c-lang-const c-opt-type-modifier-prefix-key)
+ c (c-lang-const c-type-decl-prefix-keywords-key))
+(c-lang-defvar c-maybe-typeless-specifier-re
+ (c-lang-const c-maybe-typeless-specifier-re))
+
(c-lang-defconst c-type-decl-prefix-key
"Regexp matching any declarator operator that might precede the
identifier in a declaration, e.g. the \"*\" in \"char *argv\". This