all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization
@ 2022-08-21 13:27 Naofumi Yasufuku
  2022-08-28  5:33 ` Naofumi Yasufuku
  0 siblings, 1 reply; 5+ messages in thread
From: Naofumi Yasufuku @ 2022-08-21 13:27 UTC (permalink / raw)
  To: 57318

[-- Attachment #1: Type: text/plain, Size: 2286 bytes --]

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

In cc-engine.el c-do-declarators, given CDD-NOT-TOP is non-nil at blow:

-------------------------------------------------------------
(defun c-do-declarators
    (cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function)

[..snip..]

    (while
	(and (not cdd-exhausted)
	     (setq cdd-decl-res (c-forward-declarator cdd-limit)))
      (setq cdd-next-pos (point)
	    cdd-id-start (car cdd-decl-res)
	    cdd-id-end (cadr cdd-decl-res)
	    cdd-got-func (and (eq (char-after) ?\()
			  (or (not (c-major-mode-is 'c++-mode))
			      (not cdd-not-top)  <<<< nil if "class foo<T, ..>"
			      (car (cddr (cddr cdd-decl-res))) ; Id is in
					; parens, etc.
			      (save-excursion
				(forward-char)
				(c-forward-syntactic-ws)
				(looking-at "[*&]")))
-------------------------------------------------------------

-------------------------------------------------------------
template<>>
class One<char> {
public:
    One() {}    // (not cdd-not-top): t
private:
    char _c;
};

template<typename T>
class Two<T, char> {    // "," in "class A<...>"
public:
    Two() {}    // (not cdd-not-top): nil
private:
    T _t;
    char _c;
};
-------------------------------------------------------------

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


[1] https://en.cppreference.com/w/cpp/language/partial_specialization
-------------------------------------------------------------
$ g++ -o specialization specialization.cc
$ ./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
$
-------------------------------------------------------------

Regards,
  Naofumi


[-- Attachment #2: NG --]
[-- Type: image/png, Size: 252738 bytes --]

[-- Attachment #3: OK --]
[-- Type: image/png, Size: 256368 bytes --]

[-- Attachment #4: test c++ source --]
[-- Type: text/plain, Size: 2283 bytes --]

#include <iostream>

template<typename T>
class One {
public:
    One() {}
    ~One() {}
    void fn() { std::cout << "One<T>: primary" << std::endl; }
private:
    T _t;
};

template<>
class One<char> {
public:
    One() {}
    ~One() {}
    void fn() { std::cout << "One<char>: specialization" << std::endl; }
private:
    char _c;
};

template<typename T1, typename T2>
class Two {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T1, T2>: primary" << std::endl; }
private:
    T1 _t1;
    T2 _t2;
};

template<typename T>
class Two<T, char> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, char>: specialization" << std::endl; }
private:
    T _t;
    char _c;
};

template<typename T>
class Two<T, T*> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T*>: specialization" << std::endl; }
private:
    T _t;
    T* _pt;
};

template<typename T>
class Two<T, T&> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T&>: specialization" << std::endl; }
private:
    T _t;
};

template<typename T>
class Two<T, T[]> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T[]>: specialization" << std::endl; }
private:
    T _t;
};

template<>
class Two<char, char*> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char*>: specialization" << std::endl; }
private:
    char _c;
};

template<>
class Two<char, char&> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char&>: specialization" << std::endl; }
private:
    char _c;
};

template<>
class Two<char, char[]> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char[]>: specialization" << std::endl; }
private:
    char _c;
};

int main() {
    One<int> oneInt; oneInt.fn();
    One<char> oneChar; oneChar.fn();

    Two<int, int> twoIntInt;  twoIntInt.fn();
    Two<int, char> twoIntChar; twoIntChar.fn();

    Two<int, int*> twoIntIntP; twoIntIntP.fn();
    Two<int, int&> twoIntIntR; twoIntIntR.fn();
    Two<int, int[]> twoIntIntA; twoIntIntA.fn();

    Two<char, char*> twoCharCharP; twoCharCharP.fn();
    Two<char, char&> twoCharCharR; twoCharCharR.fn();
    Two<char, char[]> twoCharCharA; twoCharCharA.fn();

    return 0;
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: patch --]
[-- Type: text/x-patch, Size: 1511 bytes --]

From f8c2d7c8d562f92ab9d8eb22a8f661f5ceb6e39c Mon Sep 17 00:00:00 2001
From: Naofumi Yasufuku <naofumi@yasufuku.dev>
Date: Sun, 21 Aug 2022 21:06:13 +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[], ...>" (partial template specialization).
---
 lisp/progmodes/cc-engine.el | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index bc6155dd66..f5d81cb530 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6141,13 +6141,16 @@ 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))
+	      (setq s (cons -1 (cdr s))))) ; for "class foo<T, T*, T&, T[] ...>"
 	 ((and (equal match ":")
 	       s
 	       (eq (car s) 0))
-	  (setq s (cons -1 (cdr s))))
-	 ((and (equal match ",")
-	       (eq (car s) -1)))	; at "," in "class foo : bar, ..."
+	  (setq s (cons -1 (cdr s)))) ; for "," in "class foo : bar, ..."
+	 ((and (member match '("*" ","))
+	       (eq (car s) -1))) ; in "class foo : ..." or "class foo<...>"
 	 ((member match '(";" "*" "," ")"))
 	  (when (and s (cdr s) (<= (car s) 0))
 	    (setq s (cdr s))))
-- 
2.37.2


[-- Attachment #6: Type: text/plain, Size: 27611 bytes --]



In GNU Emacs 29.0.50 (build 1, x86_64-apple-darwin21.6.0, NS appkit-2113.60 Version 12.5.1 (Build 21G83))
 of 2022-08-20 built on hyperion.local
Repository revision: b2f9c4c6d4bf4a0f1f1f7342cb9de410f187c40c
Repository branch: master
Windowing system distributor 'Apple', version 10.3.2113
System Description:  macOS 12.5.1

Configured using:
 'configure --prefix=/Users/naofumi/.local/emacs/head --with-ns
 --disable-ns-self-contained --with-mailutils --with-native-compilation
 --with-xwidgets'

Configured features:
ACL GIF GLIB GMP GNUTLS JPEG JSON LCMS2 LIBXML2 MODULES NATIVE_COMP
NOTIFY KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS WEBP XIM XWIDGETS ZLIB

Important settings:
  value of $LC_MESSAGES: en_US.UTF-8
  value of $LC_TIME: C
  value of $LANG: ja_JP.UTF-8
  locale-coding-system: utf-8-hfs

Major mode: Magit

Minor modes in effect:
  editorconfig-mode: t
  delete-selection-mode: t
  global-so-long-mode: t
  recentf-mode: t
  global-whitespace-mode: t
  winner-mode: t
  global-git-gutter-mode: t
  projectile-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  marginalia-mode: t
  vertico-mode: t
  savehist-mode: t
  corfu-history-mode: t
  corfu-indexed-mode: t
  corfu-terminal-mode: t
  windmove-mode: t
  disable-mouse-global-mode: t
  which-key-mode: t
  doom-modeline-mode: t
  global-corfu-mode: t
  corfu-mode: t
  pyvenv-tracking-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  global-auto-revert-mode: t
  shell-dirtrack-mode: t
  key-chord-mode: t
  override-global-mode: t
  straight-use-package-mode: t
  straight-package-neutering-mode: t
  straight-live-modifications-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tab-bar-history-mode: t
  tab-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/Users/naofumi/.emacs.d/straight/build-29/cmake-mode/cmake-mode hides /usr/local/share/emacs/site-lisp/cmake/cmake-mode
/Users/naofumi/.emacs.d/straight/build-29/ninja-mode/ninja-mode hides /usr/local/share/emacs/site-lisp/ninja/ninja-mode
/Users/naofumi/.emacs.d/straight/build-29/password-store/password-store hides /usr/local/share/emacs/site-lisp/pass/password-store
/Users/naofumi/.emacs.d/straight/build-29/transient/transient hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/transient
/Users/naofumi/.emacs.d/straight/build-29/jsonrpc/jsonrpc hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/jsonrpc
/Users/naofumi/.emacs.d/straight/build-29/org/ob-comint hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-comint
/Users/naofumi/.emacs.d/straight/build-29/org/ob-exp hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-exp
/Users/naofumi/.emacs.d/straight/build-29/org/org-ctags hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-ctags
/Users/naofumi/.emacs.d/straight/build-29/org/ob-emacs-lisp hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-emacs-lisp
/Users/naofumi/.emacs.d/straight/build-29/org/oc hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/oc
/Users/naofumi/.emacs.d/straight/build-29/org/ox-texinfo hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-texinfo
/Users/naofumi/.emacs.d/straight/build-29/org/ol-irc hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-irc
/Users/naofumi/.emacs.d/straight/build-29/org/ol-doi hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-doi
/Users/naofumi/.emacs.d/straight/build-29/org/ob hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob
/Users/naofumi/.emacs.d/straight/build-29/org/org-refile hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-refile
/Users/naofumi/.emacs.d/straight/build-29/org/org-version hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-version
/Users/naofumi/.emacs.d/straight/build-29/org/org-num hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-num
/Users/naofumi/.emacs.d/straight/build-29/org/ol-mhe hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-mhe
/Users/naofumi/.emacs.d/straight/build-29/org/ob-shell hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-shell
/Users/naofumi/.emacs.d/straight/build-29/org/org-attach hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-attach
/Users/naofumi/.emacs.d/straight/build-29/org/ob-C hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-C
/Users/naofumi/.emacs.d/straight/build-29/org/org-macs hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-macs
/Users/naofumi/.emacs.d/straight/build-29/org/org-entities hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-entities
/Users/naofumi/.emacs.d/straight/build-29/org/ob-dot hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-dot
/Users/naofumi/.emacs.d/straight/build-29/org/ob-sql hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-sql
/Users/naofumi/.emacs.d/straight/build-29/org/ol-eww hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-eww
/Users/naofumi/.emacs.d/straight/build-29/org/org-datetree hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-datetree
/Users/naofumi/.emacs.d/straight/build-29/org/org-macro hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-macro
/Users/naofumi/.emacs.d/straight/build-29/org/ob-eval hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-eval
/Users/naofumi/.emacs.d/straight/build-29/org/ob-haskell hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-haskell
/Users/naofumi/.emacs.d/straight/build-29/org/ox-org hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-org
/Users/naofumi/.emacs.d/straight/build-29/org/ol-rmail hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-rmail
/Users/naofumi/.emacs.d/straight/build-29/org/ob-awk hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-awk
/Users/naofumi/.emacs.d/straight/build-29/org/ob-groovy hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-groovy
/Users/naofumi/.emacs.d/straight/build-29/org/ox-icalendar hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-icalendar
/Users/naofumi/.emacs.d/straight/build-29/org/ob-octave hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-octave
/Users/naofumi/.emacs.d/straight/build-29/org/ob-scheme hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-scheme
/Users/naofumi/.emacs.d/straight/build-29/org/org-mobile hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-mobile
/Users/naofumi/.emacs.d/straight/build-29/org/ob-processing hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-processing
/Users/naofumi/.emacs.d/straight/build-29/org/oc-biblatex hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/oc-biblatex
/Users/naofumi/.emacs.d/straight/build-29/org/oc-csl hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/oc-csl
/Users/naofumi/.emacs.d/straight/build-29/org/org-colview hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-colview
/Users/naofumi/.emacs.d/straight/build-29/org/ob-R hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-R
/Users/naofumi/.emacs.d/straight/build-29/org/org-table hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-table
/Users/naofumi/.emacs.d/straight/build-29/org/ox-html hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-html
/Users/naofumi/.emacs.d/straight/build-29/org/ob-fortran hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-fortran
/Users/naofumi/.emacs.d/straight/build-29/org/ol hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol
/Users/naofumi/.emacs.d/straight/build-29/org/ob-plantuml hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-plantuml
/Users/naofumi/.emacs.d/straight/build-29/org/ol-docview hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-docview
/Users/naofumi/.emacs.d/straight/build-29/org/ob-perl hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-perl
/Users/naofumi/.emacs.d/straight/build-29/org/ob-sqlite hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-sqlite
/Users/naofumi/.emacs.d/straight/build-29/org/oc-basic hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/oc-basic
/Users/naofumi/.emacs.d/straight/build-29/org/ob-sed hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-sed
/Users/naofumi/.emacs.d/straight/build-29/org/ob-ditaa hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-ditaa
/Users/naofumi/.emacs.d/straight/build-29/org/ob-ruby hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-ruby
/Users/naofumi/.emacs.d/straight/build-29/org/org-habit hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-habit
/Users/naofumi/.emacs.d/straight/build-29/org/org-loaddefs hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-loaddefs
/Users/naofumi/.emacs.d/straight/build-29/org/ol-gnus hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-gnus
/Users/naofumi/.emacs.d/straight/build-29/org/ob-screen hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-screen
/Users/naofumi/.emacs.d/straight/build-29/org/org-mouse hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-mouse
/Users/naofumi/.emacs.d/straight/build-29/org/ob-css hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-css
/Users/naofumi/.emacs.d/straight/build-29/org/org-inlinetask hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-inlinetask
/Users/naofumi/.emacs.d/straight/build-29/org/ob-lisp hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-lisp
/Users/naofumi/.emacs.d/straight/build-29/org/ol-eshell hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-eshell
/Users/naofumi/.emacs.d/straight/build-29/org/org-pcomplete hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-pcomplete
/Users/naofumi/.emacs.d/straight/build-29/org/org-lint hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-lint
/Users/naofumi/.emacs.d/straight/build-29/org/org-id hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-id
/Users/naofumi/.emacs.d/straight/build-29/org/org-capture hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-capture
/Users/naofumi/.emacs.d/straight/build-29/org/ob-sass hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-sass
/Users/naofumi/.emacs.d/straight/build-29/org/ob-tangle hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-tangle
/Users/naofumi/.emacs.d/straight/build-29/org/ob-calc hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-calc
/Users/naofumi/.emacs.d/straight/build-29/org/ob-java hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-java
/Users/naofumi/.emacs.d/straight/build-29/org/org-compat hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-compat
/Users/naofumi/.emacs.d/straight/build-29/org/org-attach-git hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-attach-git
/Users/naofumi/.emacs.d/straight/build-29/org/ox-beamer hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-beamer
/Users/naofumi/.emacs.d/straight/build-29/org/org-protocol hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-protocol
/Users/naofumi/.emacs.d/straight/build-29/org/org-element hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-element
/Users/naofumi/.emacs.d/straight/build-29/org/ob-lob hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-lob
/Users/naofumi/.emacs.d/straight/build-29/org/org-tempo hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-tempo
/Users/naofumi/.emacs.d/straight/build-29/org/ob-python hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-python
/Users/naofumi/.emacs.d/straight/build-29/org/ob-latex hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-latex
/Users/naofumi/.emacs.d/straight/build-29/org/ol-w3m hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-w3m
/Users/naofumi/.emacs.d/straight/build-29/org/org-agenda hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-agenda
/Users/naofumi/.emacs.d/straight/build-29/org/ob-ocaml hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-ocaml
/Users/naofumi/.emacs.d/straight/build-29/org/ob-ref hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-ref
/Users/naofumi/.emacs.d/straight/build-29/org/ob-julia hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-julia
/Users/naofumi/.emacs.d/straight/build-29/org/ob-lilypond hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-lilypond
/Users/naofumi/.emacs.d/straight/build-29/org/ob-table hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-table
/Users/naofumi/.emacs.d/straight/build-29/org/ob-clojure hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-clojure
/Users/naofumi/.emacs.d/straight/build-29/org/org-indent hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-indent
/Users/naofumi/.emacs.d/straight/build-29/org/org-plot hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-plot
/Users/naofumi/.emacs.d/straight/build-29/org/ox-latex hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-latex
/Users/naofumi/.emacs.d/straight/build-29/org/org-src hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-src
/Users/naofumi/.emacs.d/straight/build-29/org/org-duration hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-duration
/Users/naofumi/.emacs.d/straight/build-29/org/ob-makefile hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-makefile
/Users/naofumi/.emacs.d/straight/build-29/org/ol-info hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-info
/Users/naofumi/.emacs.d/straight/build-29/org/org-clock hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-clock
/Users/naofumi/.emacs.d/straight/build-29/org/ob-forth hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-forth
/Users/naofumi/.emacs.d/straight/build-29/org/ox-odt hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-odt
/Users/naofumi/.emacs.d/straight/build-29/org/ol-man hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-man
/Users/naofumi/.emacs.d/straight/build-29/org/ox-publish hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-publish
/Users/naofumi/.emacs.d/straight/build-29/org/org-archive hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-archive
/Users/naofumi/.emacs.d/straight/build-29/org/ob-org hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-org
/Users/naofumi/.emacs.d/straight/build-29/org/ob-lua hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-lua
/Users/naofumi/.emacs.d/straight/build-29/org/org-keys hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-keys
/Users/naofumi/.emacs.d/straight/build-29/org/ob-eshell hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-eshell
/Users/naofumi/.emacs.d/straight/build-29/org/org-faces hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-faces
/Users/naofumi/.emacs.d/straight/build-29/org/ox-man hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-man
/Users/naofumi/.emacs.d/straight/build-29/org/org-list hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-list
/Users/naofumi/.emacs.d/straight/build-29/org/ox-md hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-md
/Users/naofumi/.emacs.d/straight/build-29/org/org-goto hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-goto
/Users/naofumi/.emacs.d/straight/build-29/org/ol-bbdb hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-bbdb
/Users/naofumi/.emacs.d/straight/build-29/org/org hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org
/Users/naofumi/.emacs.d/straight/build-29/org/ol-bibtex hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ol-bibtex
/Users/naofumi/.emacs.d/straight/build-29/org/ox-koma-letter hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-koma-letter
/Users/naofumi/.emacs.d/straight/build-29/org/ox-ascii hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox-ascii
/Users/naofumi/.emacs.d/straight/build-29/org/ob-matlab hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-matlab
/Users/naofumi/.emacs.d/straight/build-29/org/ox hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ox
/Users/naofumi/.emacs.d/straight/build-29/org/org-timer hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-timer
/Users/naofumi/.emacs.d/straight/build-29/org/oc-natbib hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/oc-natbib
/Users/naofumi/.emacs.d/straight/build-29/org/ob-core hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-core
/Users/naofumi/.emacs.d/straight/build-29/org/org-feed hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-feed
/Users/naofumi/.emacs.d/straight/build-29/org/ob-gnuplot hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-gnuplot
/Users/naofumi/.emacs.d/straight/build-29/org/ob-js hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-js
/Users/naofumi/.emacs.d/straight/build-29/org/org-footnote hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-footnote
/Users/naofumi/.emacs.d/straight/build-29/org/ob-maxima hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/ob-maxima
/Users/naofumi/.emacs.d/straight/build-29/org/org-crypt hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/org/org-crypt
/Users/naofumi/.emacs.d/straight/build-29/let-alist/let-alist hides /Users/naofumi/src/git.sv.gnu.org/emacs/lisp/emacs-lisp/let-alist

Features:
(shadow sort mail-extr emacsbug magit-patch ispell wdired multi-vterm
vterm vterm-module term/xterm xterm sh-script smie executable textsec
uni-scripts idna-mapping uni-confusable textsec-check timezone goto-addr
magit-extras cl-print wgrep-ag ag find-dired visual-regexp-steroids
visual-regexp cc-langs cc-bytecomp network-stream url-cache macrostep-c
cmacexp macrostep pulse help-fns radix-tree consult-xref cape affe
consult-vertico consult compat-28 magit-bookmark bookmark tramp-cmds
view dired-aux gnus-dired misearch multi-isearch skk-isearch
vertico-directory cursor-sensor vertico-repeat display-line-numbers
org-duration org-clock diary-lib diary-loaddefs org-eldoc org-superstar
toc-org org-indent org-num image-file image-converter oc-basic vc-hg
vc-git vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs log-view
editorconfig-core editorconfig-core-handle editorconfig-fnmatch
face-remap editorconfig skk-cursor ccc skk-sticky skk-dcomp skk-comp
skk-look skk-server skk-study skk-hint skk-cus skk-emacs skk-macs
skk-vars skk delsel so-long recentf-ext recentf tree-widget whitespace
winner git-gutter projectile lisp-mnt yasnippet marginalia vertico
savehist corfu-history corfu-indexed corfu-terminal win-switch windmove
disable-mouse which-key doom-modeline doom-modeline-segments
doom-modeline-env doom-modeline-core all-the-icons all-the-icons-faces
data-material data-weathericons data-octicons data-fileicons
data-faicons data-alltheicons shrink-path f f-shortdoc shortdoc tramp
tramp-loaddefs trampver tramp-integration tramp-compat ls-lisp
doom-tomorrow-night-theme doom-themes doom-themes-base
doom-themes-autoloads base16-tomorrow-night-theme base16-theme
base16-theme-autoloads doom-modeline-autoloads shrink-path-autoloads
all-the-icons-autoloads vlf-setup vlf-autoloads helpful-autoloads
elisp-refs-autoloads which-key-autoloads disable-mouse-autoloads
multiple-cursors-autoloads shell-pop term disp-table ehelp
shell-pop-autoloads win-switch-autoloads w3m-autoloads
multi-vterm-autoloads vterm-autoloads multi-term-autoloads ace-link avy
ace-link-autoloads ace-jump-buffer-autoloads affe-autoloads
cape-autoloads kind-icon svg-lib kind-icon-autoloads svg-lib-autoloads
corfu-terminal-autoloads popon popon-autoloads corfu-quick corfu-info
corfu corfu-autoloads vertico-autoloads orderless orderless-autoloads
embark-consult-autoloads embark-autoloads consult-yasnippet-autoloads
consult-lsp-autoloads consult-eglot-autoloads consult-dir-autoloads
consult-ag-autoloads consult-autoloads marginalia-autoloads migemo
migemo-autoloads visual-regexp-steroids-autoloads
visual-regexp-autoloads symbol-overlay-autoloads wgrep-ag-autoloads
ag-autoloads rg vc vc-dispatcher rg-info-hack rg-menu rg-ibuffer
rg-result wgrep-rg wgrep rg-history rg-header ibuf-ext ibuffer
ibuffer-loaddefs rg-autoloads wgrep-autoloads smart-jump-python pipenv
elpy elpy-rpc pyvenv eshell esh-cmd esh-ext esh-opt esh-proc esh-io
esh-arg esh-module esh-groups esh-util elpy-shell elpy-profile
elpy-django elpy-refactor ido hideshow grep files-x etags fileloop
cus-edit cus-load smart-jump-lisp-mode smart-jump-elisp-mode
smart-jump-cc-mode smart-jump smart-jump-autoloads dumb-jump popup s
hydra lv dumb-jump-autoloads popup-autoloads dap-mode-autoloads
lsp-docker-autoloads lsp-treemacs-autoloads treemacs-autoloads
cfrs-autoloads posframe-autoloads hydra-autoloads pfuture-autoloads
ace-window-autoloads avy-autoloads bui-autoloads lsp-mode-autoloads
lv-autoloads ht-autoloads eglot array jsonrpc ert pp ewoc xref
flymake-proc flymake compile project eglot-autoloads jsonrpc-autoloads
imenu-list-autoloads devdocs-autoloads android-mode-autoloads
grip-mode-autoloads markdown-preview-mode-autoloads web-server-autoloads
markdown-toc-autoloads gradle-mode-autoloads ninja-mode-autoloads
meson-mode-autoloads cmake-mode-autoloads powershell-autoloads
csv-mode-autoloads toml-mode-autoloads yaml-mode-autoloads
groovy-mode-autoloads kotlin-mode-autoloads rng-nxml rng-valid nxml-mode
nxml-outln nxml-rap sgml-mode facemenu web-mode-autoloads
go-mode-autoloads rustic-autoloads xterm-color-autoloads
spinner-autoloads rust-mode-autoloads haskell-mode-autoloads
ein-autoloads polymode-autoloads deferred-autoloads request-autoloads
anaphora-autoloads websocket-autoloads elpy-autoloads
yasnippet-autoloads highlight-indentation-autoloads company-autoloads
pipenv-autoloads load-env-vars-autoloads pyvenv-autoloads
slime-autoloads macrostep-autoloads editorconfig-autoloads
projectile-autoloads git-timemachine-autoloads git-modes-autoloads
git-gutter-autoloads forge-list forge-commands forge-semi
forge-bitbucket buck forge-gogs gogs forge-gitea gtea forge-gitlab glab
forge-github ghub-graphql treepy gsexp ghub let-alist forge-notify
forge-revnote forge-pullreq forge-issue forge-topic yaml bug-reference
forge-post markdown-mode color forge-repo forge forge-core forge-db
closql emacsql-sqlite emacsql emacsql-compiler url-http url-auth url-gw
nsm forge-autoloads yaml-autoloads markdown-mode-autoloads
ghub-autoloads treepy-autoloads let-alist-autoloads magit-submodule
magit-obsolete magit-blame magit-stash magit-reflog magit-bisect
magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge
magit-branch magit-reset magit-files magit-refs magit-status magit
magit-repos magit-apply magit-wip magit-log which-func imenu edebug
debug backtrace magit-diff smerge-mode diff diff-mode git-commit
log-edit pcvs-util add-log magit-core magit-autorevert autorevert
magit-margin magit-transient magit-process with-editor magit-mode
magit-git magit-base magit-section crm dash compat-27 compat-26
magit-autoloads transient compat git-commit-autoloads
transient-autoloads mu4e-maildirs-extension-autoloads mu4e-autoloads
notmuch-autoloads pcase ox-gfm ox-md ox-odt rng-loc rng-uri rng-parse
rng-match rng-dt rng-util rng-pttrn nxml-parse nxml-ns nxml-enc xmltok
nxml-util ox-latex ox-icalendar org-agenda ox-html table ox-ascii
ox-publish ox org-element org-persist org-id org-refile avl-tree
generator ox-gfm-autoloads org-tree-slide-autoloads toc-org-autoloads
org-roam-autoloads magit-section-autoloads org-superstar-autoloads
ob-shell shell ob-screen ob-python python ob-C cc-mode cc-fonts cc-guess
cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs ol-eww eww
xdg url-queue thingatpt mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus
nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig
gnus-sum shr pixel-fill kinsoku url-file svg dom gnus-group gnus-undo
gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail mail-source utf7
nnoo parse-time gnus-spec gnus-int gnus-range message sendmail
yank-media puny rfc822 mml mml-sec epa derived epg rfc6068 mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums
mailabbrev gmm-utils mailheader gnus-win gnus nnheader gnus-util
text-property-search mail-utils range mm-util mail-prsvr wid-edit
ol-docview doc-view filenotify jka-compr image-mode exif dired
dired-loaddefs ol-bibtex bibtex iso8601 ol-bbdb ol-w3m ol-doi
org-link-doi org-tempo tempo org-contrib org-contrib-autoloads org ob
ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-footnote org-src
ob-comint org-pcomplete pcomplete comint ansi-color ring org-list
org-faces org-entities time-date noutline outline org-version
ob-emacs-lisp ob-core ob-eval org-cycle org-table ol org-fold
org-fold-core org-keys oc org-compat advice org-macs org-loaddefs
format-spec find-func japanese-holidays holidays holiday-loaddefs
japanese-holidays-autoloads cal-iso cal-menu calendar cal-loaddefs
pass-autoloads f-autoloads dash-autoloads password-store-otp-autoloads
password-store-autoloads with-editor-autoloads s-autoloads
auth-source-pass epg-config sr-speedbar-autoloads recentf-ext-autoloads
cua-base dabbrev w32-ime-autoloads ddskk-autoloads cdb-autoloads
ccc-autoloads edmacro kmacro exec-path-from-shell
exec-path-from-shell-autoloads finder-inf epkg-autoloads
closql-autoloads emacsql-sqlite-autoloads emacsql-autoloads
package-utils package browse-url url url-proxy url-privacy url-expand
url-methods url-history url-cookie generate-lisp-file url-domsuf
url-util mailcap url-handlers url-parse auth-source eieio eieio-core
password-cache json map byte-opt url-vars package-utils-autoloads
restart-emacs desktop frameset server restart-emacs-autoloads
use-package-chords bind-chord use-package-chords-autoloads
bind-chord-autoloads key-chord comp comp-cstr warnings icons rx
key-chord-autoloads diminish diminish-autoloads compat-autoloads
use-package use-package-ensure use-package-delight use-package-diminish
use-package-bind-key bind-key easy-mmode use-package-core
use-package-autoloads info bind-key-autoloads straight-x
straight-autoloads cl-seq cl-extra help-mode straight subr-x cl-macs gv
bytecomp byte-compile cconv cl-loaddefs cl-lib japan-util rmc iso-transl
tooltip eldoc paren electric uniquify ediff-hook vc-hooks
lisp-float-type elisp-mode mwheel term/ns-win ns-win ucs-normalize
mule-util term/common-win tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs faces cus-face macroexp files window
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget keymap hashtable-print-readable backquote threads
xwidget-internal kqueue cocoa ns lcms2 multi-tty make-network-process
native-compile emacs)

Memory information:
((conses 16 1206921 426252)
 (symbols 48 61916 0)
 (strings 32 273893 49716)
 (string-bytes 1 11169376)
 (vectors 16 155004)
 (vector-slots 8 3434018 971478)
 (floats 8 1844 3695)
 (intervals 56 46435 9214)
 (buffers 992 101))

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization
  2022-08-21 13:27 bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization Naofumi Yasufuku
@ 2022-08-28  5:33 ` Naofumi Yasufuku
  2022-08-30 20:00   ` Alan Mackenzie
  0 siblings, 1 reply; 5+ messages in thread
From: Naofumi Yasufuku @ 2022-08-28  5:33 UTC (permalink / raw)
  To: 57318

[-- Attachment #1: Type: text/plain, Size: 1682 bytes --]

Naofumi Yasufuku <naofumi@yasufuku.dev> 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


[-- Attachment #2: sizeof problem --]
[-- Type: image/png, Size: 638081 bytes --]

[-- Attachment #3: ok with patch v2 --]
[-- Type: image/png, Size: 637252 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: patch v2 --]
[-- Type: text/x-patch, Size: 1534 bytes --]

From fc88895a0daa9f43c789650ac7f0438cd2466811 Mon Sep 17 00:00:00 2001
From: Naofumi Yasufuku <naofumi@yasufuku.dev>
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


[-- Attachment #5: test c++ source --]
[-- Type: text/plain, Size: 2970 bytes --]

#include <iostream>

template<typename T>
class One {
public:
    One() {}
    ~One() {}
    void fn() { std::cout << "One<T>: primary" << std::endl; }
private:
    T _t;
};

template<>
class One<char> {
public:
    One() {}
    ~One() {}
    void fn() { std::cout << "One<char>: specialization" << std::endl; }
private:
    char _c;
};

template<typename T1, typename T2>
class Two {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T1, T2>: primary" << std::endl; }
private:
    T1 _t1;
    T2 _t2;
};

template<typename T>
class Two<T, char> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, char>: specialization" << std::endl; }
private:
    T _t;
    char _c;
};

template<typename T>
class Two<T, T*> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T*>: specialization" << std::endl; }
private:
    T _t;
    T* _pt;
};

template<typename T>
class Two<T, T&> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T&>: specialization" << std::endl; }
private:
    T _t;
};

template<typename T>
class Two<T, T[]> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<T, T[]>: specialization" << std::endl; }
private:
    T _t;
};

template<>
class Two<char, char*> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char*>: specialization" << std::endl; }
private:
    char _c;
};

template<>
class Two<char, char&> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char&>: specialization" << std::endl; }
private:
    char _c;
};

template<>
class Two<char, char[]> {
public:
    Two() {}
    ~Two() {}
    void fn() { std::cout << "Two<char, char[]>: specialization" << std::endl; }
private:
    char _c;
};

template<typename T1, size_t>
class TwoSz {
public:
    TwoSz() {}
    ~TwoSz() {}
    void fn() { std::cout << "TwoSz<T1, size_t>: primary" << std::endl; }
private:
    T1 _t1;
};

template<typename T>
class TwoSz<T, sizeof(int)> {
public:
    TwoSz() {}
    ~TwoSz() {}
    void fn() { std::cout << "TwoSz<T, sizeof(int)>: specialization" << std::endl; }
private:
    T _t1;
};

class Base1 {};
template<typename T1, size_t> class Base2 {};
template<typename T> class Derived : public Base1, Base2<T, sizeof(int)> {
public:
  Derived() {}
};

int main() {
    One<int> oneInt; oneInt.fn();
    One<char> oneChar; oneChar.fn();

    Two<int, int> twoIntInt;  twoIntInt.fn();
    Two<int, char> twoIntChar; twoIntChar.fn();

    Two<int, int*> twoIntIntP; twoIntIntP.fn();
    Two<int, int&> twoIntIntR; twoIntIntR.fn();
    Two<int, int[]> twoIntIntA; twoIntIntA.fn();

    Two<char, char*> twoCharCharP; twoCharCharP.fn();
    Two<char, char&> twoCharCharR; twoCharCharR.fn();
    Two<char, char[]> twoCharCharA; twoCharCharA.fn();

    TwoSz<int, 8> twoSzInt8; twoSzInt8.fn();
    TwoSz<int, sizeof(int)> twoSzIntSizeofI; twoSzIntSizeofI.fn();

    Derived<int> derived{};

    return 0;
}

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization
  2022-08-28  5:33 ` Naofumi Yasufuku
@ 2022-08-30 20:00   ` Alan Mackenzie
  2022-08-31 16:01     ` Naofumi Yasufuku
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Mackenzie @ 2022-08-30 20:00 UTC (permalink / raw)
  To: Naofumi Yasufuku; +Cc: 57318

Hello, Naofumi.

Thank you indeed for your bug report, and thanks even more for
diagnosing the cause and writing a patch!

I'm truly astounded that you managed to debug this problem, hidden as it
was in the fontification parts of CC Mode, which are difficult to run
with the debugger.  Respect!

Looking at your patch, I can see one or two problems with it.  The main
one is that after encountering a template opener "<", I'm a bit worried
about the accuracy of checking for the matching ">".

Looking further into the problem, it seems the misfontification bug was
triggered by the commas in the template expressions.  When there's a
comma there, the (c-forward-<>-arglist ...) call (which "; Should always
work") fails.  This failure is caused by the dynamic binding of
c-restricted-<>-arglists to t.

When this dynamic binding is instead at nil (rather than t), the
fontification works properly, with functions fontified as functions.
The reason for this faulty binding was fixing a bug report where
scrolling a buffer containing lots of templates was very slow.  Binding
c-restricted-<>-arglists to t "solved" that slowness.

That slowness had been caused by inefficient scanning of the template
structures.  I've now identified and implemented an alternative
optimisation, which doesn't cause problems with commas in templates.

So I must apologize that I won't be using your patch, but I thoroughly
appreciate the time you must have spent debugging the problem.

Can I ask you, please, to apply and test my proposed patch, which I
enclose below.  Would you please test it on your real C++ source code,
and either confirm it really works, or say what's still faulty about it.
If there are any problems with applying the patch, feel free to send me
personal email.



diff -r 8f28cf5aae11 cc-engine.el
--- a/cc-engine.el	Sat Aug 27 09:10:03 2022 +0000
+++ b/cc-engine.el	Tue Aug 30 19:46:56 2022 +0000
@@ -146,6 +146,11 @@
 ;;       Put on the brace which introduces a brace list and on the commas
 ;;       which separate the elements within it.
 ;;
+;; 'c-<>-c-types-set
+;;   This property is set on an opening angle bracket, and indicates that
+;;   any "," separators within the template/generic expression have been
+;;   marked with a 'c-type property value 'c-<>-arg-sep (see above).
+;;
 ;; 'c-awk-NL-prop
 ;;   Used in AWK mode to mark the various kinds of newlines.  See
 ;;   cc-awk.el.
@@ -6153,7 +6158,7 @@
 			(forward-char))))
 	  (backward-char)
 	  (if (let ((c-parse-and-markup-<>-arglists t)
-		    (c-restricted-<>-arglists t))
+		    c-restricted-<>-arglists)
 		(c-forward-<>-arglist nil)) ; Should always work.
 	      (when (> (point) to)
 		(setq bound-<> (point)))
@@ -8526,9 +8531,9 @@
 	arg-start-pos)
     ;; If the '<' has paren open syntax then we've marked it as an angle
     ;; bracket arglist before, so skip to the end.
-    (if (and (not c-parse-and-markup-<>-arglists)
-	     syntax-table-prop-on-<)
-
+    (if (and syntax-table-prop-on-<
+	     (or (not c-parse-and-markup-<>-arglists)
+		 (c-get-char-property (point) 'c-<>-c-types-set)))
 	(progn
 	  (forward-char)
 	  (if (and (c-go-up-list-forward)
@@ -8623,6 +8628,7 @@
 			       (c-unmark-<->-as-paren (point)))))
 		      (c-mark-<-as-paren start)
 		      (c-mark->-as-paren (1- (point)))
+		      (c-put-char-property start 'c-<>-c-types-set t)
 		      (c-truncate-lit-pos-cache start))
 		    (setq res t)
 		    nil))		; Exit the loop.
diff -r 8f28cf5aae11 cc-fonts.el
--- a/cc-fonts.el	Sat Aug 27 09:10:03 2022 +0000
+++ b/cc-fonts.el	Tue Aug 30 19:46:56 2022 +0000
@@ -937,17 +937,16 @@
     (save-excursion
       (let ((pos (point)))
 	(c-backward-syntactic-ws (max (- (point) 500) (point-min)))
-	(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
-			  c-not-decl)))
-	     (1- (point))
-	   pos)
-	 limit 'c-type)))
+	(when (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
+			   c-not-decl)))
+	  (setq pos (1- (point))))
+	(c-clear-char-properties pos limit 'c-type)
+	(c-clear-char-properties pos limit 'c-<>-c-types-set)))
 
     ;; 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,



On Sun, Aug 28, 2022 at 14:33:08 +0900, Naofumi Yasufuku wrote:
> Naofumi Yasufuku <naofumi@yasufuku.dev> 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

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization
  2022-08-30 20:00   ` Alan Mackenzie
@ 2022-08-31 16:01     ` Naofumi Yasufuku
  2022-08-31 19:26       ` Alan Mackenzie
  0 siblings, 1 reply; 5+ messages in thread
From: Naofumi Yasufuku @ 2022-08-31 16:01 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: 57318

[-- Attachment #1: Type: text/plain, Size: 2850 bytes --]

Hello Alan,

Alan Mackenzie <acm@muc.de> writes:

> Hello, Naofumi.
>
> Thank you indeed for your bug report, and thanks even more for
> diagnosing the cause and writing a patch!
>
> I'm truly astounded that you managed to debug this problem, hidden as it
> was in the fontification parts of CC Mode, which are difficult to run
> with the debugger.  Respect!
>

Thank you, I'm glad to hear that.

> Looking at your patch, I can see one or two problems with it.  The main
> one is that after encountering a template opener "<", I'm a bit worried
> about the accuracy of checking for the matching ">".
>
> Looking further into the problem, it seems the misfontification bug was
> triggered by the commas in the template expressions.  When there's a
> comma there, the (c-forward-<>-arglist ...) call (which "; Should always
> work") fails.  This failure is caused by the dynamic binding of
> c-restricted-<>-arglists to t.
>
> When this dynamic binding is instead at nil (rather than t), the
> fontification works properly, with functions fontified as functions.
> The reason for this faulty binding was fixing a bug report where
> scrolling a buffer containing lots of templates was very slow.  Binding
> c-restricted-<>-arglists to t "solved" that slowness.
>

Indeed.  I confirmed that avoiding (c-restricted-<>-arglists t) binding
solves this misfontification problem at least, but it makes scrolling
terribly slow...

> That slowness had been caused by inefficient scanning of the template
> structures.  I've now identified and implemented an alternative
> optimisation, which doesn't cause problems with commas in templates.
>
[..snip..]
> Can I ask you, please, to apply and test my proposed patch, which I
> enclose below.  Would you please test it on your real C++ source code,
> and either confirm it really works, or say what's still faulty about it.
> If there are any problems with applying the patch, feel free to send me
> personal email.
>

I've applied your patch.  It works well and solves misfontification
problem.  At the same time, I've not seen any noticeable performance
degradation by this patch so far.  Great.

  attachment: fix_c-restricted--arglists_verification.png

I came across this problem when I tried to compare the current
tree-sitter's fontification quality and performance with familiar
cc-mode by using very-fast flat_hash_map code [1][2].  Now problematic
fontification has gone.

> So I must apologize that I won't be using your patch, but I thoroughly
> appreciate the time you must have spent debugging the problem.
>

That's just fine with me.  I don't mind at all because I'm not an
expert.  Fixing the root cause should be done.

Best regards,
  Naofumi

[1] https://github.com/skarupke/flat_hash_map/blob/master/flat_hash_map.hpp
[2] https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/



[-- Attachment #2: verification --]
[-- Type: image/png, Size: 468337 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization
  2022-08-31 16:01     ` Naofumi Yasufuku
@ 2022-08-31 19:26       ` Alan Mackenzie
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Mackenzie @ 2022-08-31 19:26 UTC (permalink / raw)
  To: Naofumi Yasufuku; +Cc: 57318-done

Hello, Naofumi.

On Thu, Sep 01, 2022 at 01:01:56 +0900, Naofumi Yasufuku wrote:
> Hello Alan,

[ .... ]

> > When this dynamic binding is instead at nil (rather than t), the
> > fontification works properly, with functions fontified as functions.
> > The reason for this faulty binding was fixing a bug report where
> > scrolling a buffer containing lots of templates was very slow.  Binding
> > c-restricted-<>-arglists to t "solved" that slowness.


> Indeed.  I confirmed that avoiding (c-restricted-<>-arglists t) binding
> solves this misfontification problem at least, but it makes scrolling
> terribly slow...

Yes.  For the bug in 2019 for which I "fixed" this, the scrolling was
around a factor of 6 slower.

[ .... ]

> [..snip..]
> > Can I ask you, please, to apply and test my proposed patch, which I
> > enclose below.  Would you please test it on your real C++ source code,
> > and either confirm it really works, or say what's still faulty about it.
> > If there are any problems with applying the patch, feel free to send me
> > personal email.


> I've applied your patch.  It works well and solves misfontification
> problem.  At the same time, I've not seen any noticeable performance
> degradation by this patch so far.  Great.

Many thanks!

I've committed the patch to the standalone CC Mode repository and the
Emacs master branch at savannah.  I'm closing the bug with this post.

>   attachment: fix_c-restricted--arglists_verification.png

> I came across this problem when I tried to compare the current
> tree-sitter's fontification quality and performance with familiar
> cc-mode by using very-fast flat_hash_map code [1][2].  Now problematic
> fontification has gone.

In the long run, tree-sitter (or something like it) is going to be
superseding CC Mode.  Keeping up with the constantly evolving standards
in CC Mode has proven to be just too much work.  :-(

[ .... ]

> Best regards,
>   Naofumi

> [1] https://github.com/skarupke/flat_hash_map/blob/master/flat_hash_map.hpp
> [2] https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-08-31 19:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-21 13:27 bug#57318: 29.0.50; c++-mode: Functions are shown as variables: partial template specialization Naofumi Yasufuku
2022-08-28  5:33 ` Naofumi Yasufuku
2022-08-30 20:00   ` Alan Mackenzie
2022-08-31 16:01     ` Naofumi Yasufuku
2022-08-31 19:26       ` Alan Mackenzie

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.