Subject: Re: bug#42270: 28.0.50; cc-mode indentation issue with attributes

From: Ergus <[email-masked]>
Date: Mon, 7 Sep 2020 12:04:45 +0200

Hi Alan:

I will try it now and give you some feed back this week.

Very thanks,

On Sat, Sep 05, 2020 at 12:13:35PM +0000, Alan Mackenzie wrote:
>Hello, Ergus.
>
>Thanks for the bug report.
>
>On Wed, Jul 08, 2020 at 19:03:58 +0200, Ergus wrote:
>> Hi:
>
>> Working in C++ I am getting this indentation difference when arguments
>> has attributes or not:
>
>> TaskDataAccesses(TaskDataAccessesInfo taskAccessInfo)
>> 	: _lock(),
>> 	  _accesses(),
>> 	  _accessFragments(), _taskwaitFragments()
>> {
>> }
>
>
>> TaskDataAccesses(__attribute__((unused)) TaskDataAccessesInfo taskAccessInfo)
>> : _lock(),
>> _accesses(),
>> _accessFragments(), _taskwaitFragments()
>> {
>> }
>
>> The problem seems to be that in the first case the `:` indentation
>> symbol (C-c C-o) is recognised as `member-init-intro` (correct) but in
>> the second one it is detected as a `topmost-intro-cont` which is
>> actually wrong.
>
>Yes, indeed.  There were also problems with the fontification in similar
>fragments, e.g.:
>
>    TaskDataAccesses(foo((unused)) TaskDataAccessesInfo taskAccessInfo)
>    : _lock(),
>        _accesses(),
>        _accessFragments(), _taskwaitFragments()
>    {
>    }
>
>, where typing into "foo" removed the fontification from
>"Task...unused))", which got replaced on the next redisplay (e.g. after
>typing M-x).
>
>I think the patch below fixes all these problems.  Would you please apply
>it, rebuild CC Mode, load it, and try it out on your real source code.  A
>fairly thorough test would be appreciated, here.  Then please let me know
>if the bug is actually fixed, and whether there are any "strange things"
>happening.  Thanks!
>
>> Best,
>> Ergus
>
>> In GNU Emacs 28.0.50 (build 10, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw scroll bars)
>>  of 2020-07-07 built on ergus
>> Repository revision: df3ece9d2ed61c9526dbf718e3c96d72bd53dccb
>> Repository branch: master
>> System Description: Debian GNU/Linux 10 (buster)
>
>
>
>diff -r 877c4ad9dae8 cc-engine.el
>--- a/cc-engine.el	Sat Jul 04 16:23:06 2020 +0000
>+++ b/cc-engine.el	Sat Sep 05 11:53:51 2020 +0000
>@@ -2243,7 +2243,7 @@
>
> 	     ((and c-opt-cpp-prefix
> 		   (looking-at c-noise-macro-name-re))
>-	      ;; Skip over a noise macro.
>+	      ;; Skip over a noise macro without parens.
> 	      (goto-char (match-end 1))
> 	      (not (eobp)))
>
>@@ -9141,6 +9141,12 @@
> 				  (catch 'is-function
> 				    (while
> 					(progn
>+					  (while
>+					      (cond
>+					       ((looking-at c-decl-hangon-key)
>+						(c-forward-keyword-clause 1))
>+					       ((looking-at c-noise-macro-with-parens-name-re)
>+						(c-forward-noise-clause))))
> 					  (if (eq (char-after) ?\))
> 					      (throw 'is-function t))
> 					  (setq cdd-got-type (c-forward-type))
>@@ -9789,6 +9795,16 @@
> 				  (save-excursion
> 				    (goto-char after-paren-pos)
> 				    (c-forward-syntactic-ws)
>+				    (progn
>+				      (while
>+					  (cond
>+					   ((and
>+					     c-opt-cpp-prefix
>+					     (looking-at c-noise-macro-with-parens-name-re))
>+					    (c-forward-noise-clause))
>+					   ((looking-at c-decl-hangon-key)
>+					    (c-forward-keyword-clause 1))))
>+				      t)
> 				    (or (c-forward-type)
> 					;; Recognize a top-level typeless
> 					;; function declaration in C.
>diff -r 877c4ad9dae8 cc-mode.el
>--- a/cc-mode.el	Sat Jul 04 16:23:06 2020 +0000
>+++ b/cc-mode.el	Sat Sep 05 11:53:51 2020 +0000
>@@ -2236,7 +2236,8 @@
> (defun c-fl-decl-end (pos)
>   ;; If POS is inside a declarator, return the end of the token that follows
>   ;; the declarator, otherwise return nil.  POS being in a literal does not
>-  ;; count as being in a declarator (on pragmatic grounds).
>+  ;; count as being in a declarator (on pragmatic grounds).  POINT is not
>+  ;; preserved.
>   (goto-char pos)
>   (let ((lit-start (c-literal-start))
> 	enclosing-attribute pos1)
>@@ -2249,12 +2250,31 @@
> 	(let ((lim (save-excursion
> 		     (and (c-beginning-of-macro)
> 			  (progn (c-end-of-macro) (point))))))
>-	  (when (and (c-forward-declarator lim)
>-		     (or (not (eq (char-after) ?\())
>-			 (c-go-list-forward nil lim))
>-		     (eq (c-forward-token-2 1 nil lim) 0))
>-	    (c-backward-syntactic-ws)
>-	    (point)))))))
>+	  (and (c-forward-declarator lim)
>+	       (if (eq (char-after) ?\()
>+		   (and
>+		    (c-go-list-forward nil lim)
>+		    (progn (c-forward-syntactic-ws lim)
>+			   (not (eobp)))
>+		    (progn
>+		      (if (looking-at c-symbol-char-key)
>+			  ;; Deal with baz (foo((bar)) type var), where
>+			  ;; foo((bar)) is not semantically valid.  The result
>+			  ;; must be after var).
>+			  (and
>+			   (goto-char pos)
>+			   (setq pos1 (c-on-identifier))
>+			   (goto-char pos1)
>+			   (progn
>+			     (c-backward-syntactic-ws)
>+			     (eq (char-before) ?\())
>+			   (c-fl-decl-end (1- (point))))
>+			(c-backward-syntactic-ws)
>+			(point))))
>+		 (and (progn (c-forward-syntactic-ws lim)
>+			     (not (eobp)))
>+		      (c-backward-syntactic-ws)
>+		      (point)))))))))
>
> (defun c-change-expand-fl-region (beg end old-len)
>   ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock
>diff -r 877c4ad9dae8 cc-vars.el
>--- a/cc-vars.el	Sat Jul 04 16:23:06 2020 +0000
>+++ b/cc-vars.el	Sat Sep 05 11:53:51 2020 +0000
>@@ -1668,7 +1668,8 @@
> like \"INLINE\" which are syntactic noise.  Such a macro/extension is complete
> in itself, never having parentheses.  All these names must be syntactically
> valid identifiers.  Alternatively, this variable may be a regular expression
>-which matches the names of such macros.
>+which matches the names of such macros, in which case it must have a submatch
>+1 which matches the actual noise macro name.
>
> If you change this variable's value, call the function
> `c-make-noise-macro-regexps' to set the necessary internal variables (or do
>@@ -1683,7 +1684,8 @@
> which optionally have arguments in parentheses, and which expand to nothing.
> All these names must be syntactically valid identifiers.  These are recognized
> by CC Mode only in declarations.  Alternatively, this variable may be a
>-regular expression which matches the names of such macros.
>+regular expression which matches the names of such macros, in which case it
>+must have a submatch 1 which matches the actual noise macro name.
>
> If you change this variable's value, call the function
> `c-make-noise-macro-regexps' to set the necessary internal variables (or do
>
>
>-- 
>Alan Mackenzie (Nuremberg, Germany).