Subject: Re: bug#64204: C/C++ local variables not syntax highlighted if they start with $

From: Alan Mackenzie <[email-masked]>
Date: Wed, 21 Jun 2023 19:25:41 +0000

Hello, Joseph and Po.

On Wed, Jun 21, 2023 at 19:51:50 +0800, Po Lu wrote:
> Joseph Garvin <[email-masked]> writes:

> > Start emacs with `emacs -Q`, press C-x C-f and type in a filename that
> > ends in .cpp like "foo.cpp". Then type in:

> > int main()
> > {
> >     int a = 0;
> >     int b = 0;
> >     int $ = 0;
> >     int d$ = 0;
> >     int $e = 0;
> > }

> > Yes it compiles! GCC, Clang, and MSVC all have a non-standard
> > extension that allows $ signs to appear in C/C++ variable and type
> > names: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html

> > Then a,b,d$ will be highlighted correctly as local vars, but not $ or
> > $e. The highlighting doesn't appear to work whenever $ is the first or
> > only character. Since emacs is accepting of the $ sign anywhere else in
> > the variable name, I suspect supporting $ was intended, even though it's
> > non-standard. Even if not intended, it's a popular syntax
> > extension supported by the major current compilers and whose history
> > goes back to the DEC compiler, so support would be nice.

> This is a bug indeed.  Alan, would you please look into this?

OK, I've amended C Mode, C++ Mode and Objective C Mode to fontify
identifiers starting with a $.

Please apply the patch below to .../lisp/progmodes/cc-langs.el, and
(since Lisp macros have been changed) recompile the entire CC Mode files
and reload them.  (Joseph, if you want any help with the patching or
compiling, feel free to send me private email.)  Then please try out the
new version on your real code, and confirm to me that the bug has been
fixed, or tell me what's still wrong.

Thanks!

diff -r c45cc2208ed4 cc-langs.el
--- a/cc-langs.el	Wed Jun 21 14:58:04 2023 +0000
+++ b/cc-langs.el	Wed Jun 21 19:14:40 2023 +0000
@@ -819,8 +819,9 @@
 keyword.  It's unspecified how far it matches.  Does not contain a \\|
 operator at the top level."
   t    (concat "[" c-alpha "_]")
+  (c c++) (concat "[" c-alpha "_$]")
   java (concat "[" c-alpha "_@]")
-  objc (concat "[" c-alpha "@]")
+  objc (concat "[" c-alpha "@$]")
   pike (concat "[" c-alpha "_`]"))
 (c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
 
@@ -844,9 +845,10 @@
   t    (concat (c-lang-const c-symbol-start)
 	       "[" (c-lang-const c-symbol-chars) "]\\{,1000\\}")
   pike (concat
-	;; Use the value from C here since the operator backquote is
+	;; Use the value from AWK here since the operator backquote is
 	;; covered by the other alternative.
-	(c-lang-const c-symbol-key c)
+	(c-lang-const c-symbol-key awk
+		      )
 	"\\|"
 	(c-make-keywords-re nil
 	  (c-lang-const c-overloadable-operators))))

-- 
Alan Mackenzie (Nuremberg, Germany).