bug#58534: CC Mode 5.35.1 (C/*l); Incorrect fontification of params as types

Alan Mackenzie <[email protected]> Sat, 15 Oct 2022 12:00:53 +0000
Newsgroups gmane.emacs.cc-mode.general
Message-ID <Y0qg9TXKjQVG2LLa@ACM>
Hello again, Po.

On Sat, Oct 15, 2022 at 19:24:24 +0800, Po Lu wrote:
> Alan Mackenzie <[email protected]> writes:

> > Thanks for the bug report, thanks also for the CC Mode configuration
> > dump.

> > I think I know what's causing the bug; With "struct wl_surface", CC Mode
> > decides "wl_surface" is a type, and thus fontifies occurrences of
> > "wl_surface" as types.  Unfortunately, there are variables of this name,
> > too.

> > Give me a little time, and I will come up with a solution.

> Thanks.

The solution seems to be not to add foo to c-found-types on encountering
struct foo, but to continue doing so (in C++) for typename foo.

Would you please try out the following patch, and let me know if it
works OK.  Also could you check whether the patch also fixes bug #58537,
please.

Thanks!


diff -r 0e4b43dec11c cc-engine.el
--- a/cc-engine.el	Fri Oct 14 17:13:47 2022 +0000
+++ b/cc-engine.el	Sat Oct 15 11:44:29 2022 +0000
@@ -9077,7 +9077,8 @@
     (c-forward-<>-arglist t)
     (c-forward-syntactic-ws))
 
-  (let ((start (point)) pos res name-res id-start id-end id-range)
+  (let ((start (point)) pos res name-res id-start id-end id-range
+	post-prefix-pos)
 
     ;; Skip leading type modifiers.  If any are found we know it's a
     ;; prefix of a type.
@@ -9089,6 +9090,7 @@
 	(c-forward-syntactic-ws)
 	(or (eq res 'no-id)
 	    (setq res 'prefix))))
+    (setq post-prefix-pos (point))
 
     (cond
      ((looking-at c-typeof-key) ; e.g. C++'s "decltype".
@@ -9121,9 +9123,12 @@
       (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))
+	;; With some keywords the name can be used without the prefix, so we
+	;; add the name to `c-found-types' when this is the case.
+	(when (save-excursion
+		(goto-char post-prefix-pos)
+		(looking-at c-self-contained-typename-key))
+	  (c-add-type pos (point)))
 	(when (and c-record-type-identifiers
 		   c-last-identifier-range)
 	  (c-record-type-id c-last-identifier-range)))
diff -r 0e4b43dec11c cc-langs.el
--- a/cc-langs.el	Fri Oct 14 17:13:47 2022 +0000
+++ b/cc-langs.el	Sat Oct 15 11:44:29 2022 +0000
@@ -2280,11 +2280,21 @@
 C++ Mode, e.g. \"<typename X = Y>\"."
   t    nil
   c++  '("class" "typename"))
-
 (c-lang-defconst c-template-typename-key
   t (c-make-keywords-re t (c-lang-const c-template-typename-kwds)))
 (c-lang-defvar c-template-typename-key (c-lang-const c-template-typename-key))
 
+(c-lang-defconst c-self-contained-typename-kwds
+  "Keywords where the following name is a type name which can be
+used in declarations without the keyword."
+  t    nil
+  c++  '("typename"))
+(c-lang-defconst c-self-contained-typename-key
+  ;; Adorned regexp matching `c-self-contained-typename-key'.
+  t (c-make-keywords-re t (c-lang-const c-self-contained-typename-kwds)))
+(c-lang-defvar c-self-contained-typename-key
+	       (c-lang-const c-self-contained-typename-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


-- 
Alan Mackenzie (Nuremberg, Germany).