Subject: bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization

From: Naofumi Yasufuku <[email-masked]>
Date: Sun, 28 Aug 2022 14:33:08 +0900

Naofumi Yasufuku <[email-masked]> writes:

> Hello,
>
> In the case of C++ partial template specialization [1], functions are
> shown as variables.  Please look at the attached screenshots.
>
>   1. emacs -Q
>   2. open attached C++ code "specialization.cc"
>
>   attachments:
>   - NG_cc-partial-specialization.png
>   - OK_cc-partial-specialization.png
>   - specialization.cc
>
[..snip..]
>
> After a brief investigation, the attached cc-engine.el patch seems to
> solve this issue at least, but it is not tested enough.
>
>   attachments:
>   - 0001-cc-mode-Fix-function-fontification-in-the-case-of-C-.patch
>

Previous patch still has a problem with sizeof() specializations.
Updated patch and screenshots are attached.

  attachments:
  - 0001-cc-mode-Fix-function-fontification-in-the-case-of-C-v2.patch
  - NG_cc-partial-specialization-v1.png
  - OK_cc-partial-specialization-v2.png
  - specialization.cc

-------------------------------------------------------------
template<typename T1, size_t>
class TwoSz {
public:
    TwoSz() {}
private:
    T1 _t1;
};

template<typename T>
class TwoSz<T, sizeof(int)> {
public:
    TwoSz() {}
private:
    T _t1;
};
-------------------------------------------------------------
$ ./specialization
One<T>: primary
One<char>: specialization
Two<T1, T2>: primary
Two<T, char>: specialization
Two<T, T*>: specialization
Two<T, T&>: specialization
Two<T, T[]>: specialization
Two<char, char*>: specialization
Two<char, char&>: specialization
Two<char, char[]>: specialization
TwoSz<T1, size_t>: primary
TwoSz<T, sizeof(int)>: specialization
$
-------------------------------------------------------------

Best regards,
  Naofumi

>From fc88895a0daa9f43c789650ac7f0438cd2466811 Mon Sep 17 00:00:00 2001
From: Naofumi Yasufuku <[email-masked]>
Date: Sun, 28 Aug 2022 13:33:01 +0900
Subject: [PATCH] cc-mode: Fix function fontification in the case of C++
 partial specialization

* lisp/progmodes/cc-engine.el (c-update-brace-stack): Skip "*", ",",
and ")" found in "class foo : bar, .." (base-clause of a class) or
"class foo<T, T*, T&, T[], sizeof(..), ..>" (partial template specialization)
(bug#57318).
---
 lisp/progmodes/cc-engine.el | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b2d1f15d39..5d1a11e9e8 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6141,13 +6141,18 @@ c-update-brace-stack
 		(c-forward-<>-arglist nil)) ; Should always work.
 	      (when (> (point) to)
 		(setq bound-<> (point)))
-	    (forward-char)))
+	    (forward-char))
+	  (if (and s
+		   (eq (car s) 0))
+	      ;; for "class foo<T, T*, T&, T[], sizeof(..), ..>"
+	      (setq s (cons -1 (cdr s)))))
 	 ((and (equal match ":")
 	       s
 	       (eq (car s) 0))
+	  ;; for "," in "class foo : bar, .."
 	  (setq s (cons -1 (cdr s))))
-	 ((and (equal match ",")
-	       (eq (car s) -1)))	; at "," in "class foo : bar, ..."
+	 ((and (eq (car s) -1) ; in "class foo : .." or "class foo<..>"
+	       (member match '("*" "," ")"))))
 	 ((member match '(";" "*" "," ")"))
 	  (when (and s (cdr s) (<= (car s) 0))
 	    (setq s (cdr s))))
-- 
2.37.2