Subject: Re: bug#23610: 25.0.94; c++-mode doesn't fontify typename... like typename

From: Alan Mackenzie <[email-masked]>
Date: Thu, 30 Jun 2016 17:24:32 +0000

Hello again, Ivan.

On Wed, Jun 22, 2016 at 09:22:01AM -0600, Ivan Andrus wrote:
> On Sun, Jun 19, 2016 at 3:14 PM, Alan Mackenzie <[email-masked]> wrote:
> > Hello, Ivan.

> > In article <[email-masked]> you wrote:
> >> Starting with emacs -Q, Y is not fontified in the snippet below, whereas
> >> X is.

> >> -Ivan

> >> template <typename X, typename... Y>
> >> class bob {

> >> };

> > [ .... ]

> > The following patch is a first attempt to fontify parameter packs.  After
> > applying it, please be sure either to recompile CC Mode entirely, or
> > first to compile cc-langs.el (which contains macros), and then all three
> > of cc-fonts.el, cc-engine.el, and cc-mode.el.

> > It seems to fontify the "Y" above OK.  I've tried it on a stock example
> > out of Wikipedia, and that works.  Could you try it out on your code,
> > please, and let me know how well it works.

> It looks pretty good.  I didn't notice this before, but the following example
> from Wikipedia is fontified differently if the ... is removed from before the
> `args`.  In that case args is fontified with `font-lock-variable-name-face`.

>   template<typename... Args> inline void expand(Args&&... args) {
>     pass( some_function(args)... );
>   }

OK.  I think the patch below fixes it.  Please try it out and report
back.  (Same instructions about recompilation of CC Mode as last time
apply, since further macros in cc-langs.el have been modified).  Please
note that the patch below is complete in itself, it isn't incremental,
based on the last patch.  It's based on a current Emacs master branch.

diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 48b9e5e..cc60175 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -7090,6 +7090,9 @@ c-forward-type
       (while (cond
 	      ((looking-at c-decl-hangon-key)
 	       (c-forward-keyword-clause 1))
+	      ((looking-at c-pack-key)
+	       (goto-char (match-end 1))
+	       (c-forward-syntactic-ws))
 	      ((and c-opt-cpp-prefix
 		    (looking-at c-noise-macro-with-parens-name-re))
 	       (c-forward-noise-clause))))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 4d36684..b903190 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1329,6 +1329,14 @@ 'c-opt-op-identitier-prefix
 (c-lang-defvar c-stmt-delim-chars-with-comma
   (c-lang-const c-stmt-delim-chars-with-comma))
 
+(c-lang-defconst c-pack-ops
+  "Ops which signal C++11's \"parameter pack\""
+  t nil
+  c++ '("..."))
+(c-lang-defconst c-pack-key
+  t (c-make-keywords-re 'appendable (c-lang-const c-pack-ops)))
+(c-lang-defvar c-pack-key (c-lang-const c-pack-key))
+
 (c-lang-defconst c-auto-ops
   ;; Ops which signal C++11's new auto uses.
   t nil
@@ -2958,6 +2966,10 @@ 'c-opt-op-identitier-prefix
 		   "\\)"
 		   "\\([^=]\\|$\\)")
   c++  (concat "\\("
+	       "&&"
+	       "\\|"
+	       "\\.\\.\\."
+	       "\\|"
 	       "[*(&]"
 	       "\\|"
 	       (c-lang-const c-type-decl-prefix-key)

> -Ivan

-- 
Alan Mackenzie (Nuremberg, Germany).