From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent Date: Sat, 12 Oct 2013 20:45:43 +0000 Message-ID: <20131012204542.GA3690@acm.acm> References: <160417FD-FE6F-4C7F-AEC5-CEFD09ABE113@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1381610911 24673 80.91.229.3 (12 Oct 2013 20:48:31 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 12 Oct 2013 20:48:31 +0000 (UTC) Cc: 15415@debbugs.gnu.org To: Ivan Andrus Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Oct 12 22:48:34 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VV670-0006SR-7l for geb-bug-gnu-emacs@m.gmane.org; Sat, 12 Oct 2013 22:48:34 +0200 Original-Received: from localhost ([::1]:59315 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV66z-0004X9-N5 for geb-bug-gnu-emacs@m.gmane.org; Sat, 12 Oct 2013 16:48:33 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:32815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV66p-0004VP-CE for bug-gnu-emacs@gnu.org; Sat, 12 Oct 2013 16:48:30 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VV66i-0006nh-0P for bug-gnu-emacs@gnu.org; Sat, 12 Oct 2013 16:48:23 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:58903) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV66U-0006lI-MP; Sat, 12 Oct 2013 16:48:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1VV66U-0003sv-2z; Sat, 12 Oct 2013 16:48:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Sat, 12 Oct 2013 20:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 15415 X-GNU-PR-Package: emacs,cc-mode X-GNU-PR-Keywords: Original-Received: via spool by 15415-submit@debbugs.gnu.org id=B15415.138161086614911 (code B ref 15415); Sat, 12 Oct 2013 20:48:02 +0000 Original-Received: (at 15415) by debbugs.gnu.org; 12 Oct 2013 20:47:46 +0000 Original-Received: from localhost ([127.0.0.1]:44689 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1VV66D-0003sQ-Ny for submit@debbugs.gnu.org; Sat, 12 Oct 2013 16:47:46 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:55026 helo=mail.muc.de) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1VV669-0003sG-RW for 15415@debbugs.gnu.org; Sat, 12 Oct 2013 16:47:43 -0400 Original-Received: (qmail 11722 invoked by uid 3782); 12 Oct 2013 20:47:39 -0000 Original-Received: from acm.muc.de (p5492CE06.dip0.t-ipconnect.de [84.146.206.6]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 12 Oct 2013 22:47:38 +0200 Original-Received: (qmail 3917 invoked by uid 1000); 12 Oct 2013 20:45:43 -0000 Content-Disposition: inline In-Reply-To: <160417FD-FE6F-4C7F-AEC5-CEFD09ABE113@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:79217 Archived-At: Hello, Ivan. On Sun, Sep 29, 2013 at 09:31:13PM -0600, Ivan Andrus wrote: > Ivan Andrus writes: > > Font locking of C++ constructors is somewhat inconsistent. This is > > no doubt complicated by the fact that unlike other function > > declarations they "don't have a return type". This is, indeed, problematic. > > When a single argument is not used but named, the constructor is not > > fontified (normally it's fontified with > > `font-lock-function-name-face'). If the keyword explicit is used, > > then the argument type is fontified as a variable, and the > > constructor name is fontified as a type. Perhaps interestingly, > > naming the parameter or adding another parameter causes fontification > > to work correctly (with or without explicit). Yes. The pertinent function, `c-forward-decl-or-cast-1', is somewhat probablistic. If it gets sufficient clues from the context, it gets things right, otherwise it has to guess, and sometimes will get things wrong, particularly in C++, which doesn't have a nice context-free syntax. > > I have included a sample file below with comments on what I see in > > `emacs -q` > > class Bob > > { > > // string is `font-lock-type-face', Bob is `font-lock-function-name-face' 1 > > Bob( string bob ); > > // string and Bob are not fontified (though I sometimes see string fontified as a type) 2 > > Bob( string ); > > // string is `font-lock-variable-name-face', Bob is `font-lock-type-face' 3 > > explicit Bob( string ); > > // string is `font-lock-type-face', Bob is `font-lock-function-name-face' 4 > > explicit Bob( string, string ); > > }; > In fact, it's not just constructors that have this problem. For > example the following function declaration: 5 > string lookup( size_t ) const; > Removing const, or adding a name to the size_t parameter causes > fontification to work correctly. Yes. Of the lines of code you've illustrated, 1 and 4 were OK. I've corrected 3 and 5, which were relatively simple. 2 is a problem, because it looks like a normal function call. If the identifier in the parentheses (here "string") can be positively identified as a type (for example, some use elsewhere can only be a type, or it's a standard type like "string") it gets fontified. Otherwise, it's assumed the construct is a function call. It would no doubt be possible to check that the enclosing braces are a class declaration, and that "Bob" is the name of the class, but this would slow down the fontification, probably by a lot. Would you please try out the patch below, and let me know how it goes. It is based on the current source in the bzr trunk. Again, thanks for such a crisp and concise bug report. === modified file 'lisp/progmodes/cc-engine.el' *** lisp/progmodes/cc-engine.el 2013-09-28 17:17:01 +0000 --- lisp/progmodes/cc-engine.el 2013-10-12 20:18:26 +0000 *************** *** 6917,6923 **** ;; can happen since we don't know if ;; `c-restricted-<>-arglists' will be correct inside the ;; arglist paren that gets entered. ! c-parse-and-markup-<>-arglists) (goto-char id-start) --- 6917,6925 ---- ;; can happen since we don't know if ;; `c-restricted-<>-arglists' will be correct inside the ;; arglist paren that gets entered. ! c-parse-and-markup-<>-arglists ! ;; Start of the identifier for which `got-identifier' was set. ! name-start) (goto-char id-start) *************** *** 6935,6941 **** ;; If the third submatch matches in C++ then ;; we're looking at an identifier that's a ;; prefix only if it specifies a member pointer. ! (when (setq got-identifier (c-forward-name)) (if (looking-at "\\(::\\)") ;; We only check for a trailing "::" and ;; let the "*" that should follow be --- 6937,6945 ---- ;; If the third submatch matches in C++ then ;; we're looking at an identifier that's a ;; prefix only if it specifies a member pointer. ! (when (progn (setq pos (point)) ! (setq got-identifier (c-forward-name))) ! (setq name-start pos) (if (looking-at "\\(::\\)") ;; We only check for a trailing "::" and ;; let the "*" that should follow be *************** *** 6961,6967 **** ;; Skip over an identifier. (or got-identifier (and (looking-at c-identifier-start) ! (setq got-identifier (c-forward-name)))) ;; Skip over type decl suffix operators. (while (if (looking-at c-type-decl-suffix-key) --- 6965,6973 ---- ;; Skip over an identifier. (or got-identifier (and (looking-at c-identifier-start) ! (setq pos (point)) ! (setq got-identifier (c-forward-name)) ! (setq name-start pos))) ;; Skip over type decl suffix operators. (while (if (looking-at c-type-decl-suffix-key) *************** *** 7052,7074 **** ;; declaration. (throw 'at-decl-or-cast t)) - (when (and got-parens - (not got-prefix) - (not got-suffix-after-parens) - (or backup-at-type - maybe-typeless - backup-maybe-typeless)) - ;; Got a declaration of the form "foo bar (gnu);" where we've - ;; recognized "bar" as the type and "gnu" as the declarator. - ;; In this case it's however more likely that "bar" is the - ;; declarator and "gnu" a function argument or initializer (if - ;; `c-recognize-paren-inits' is set), since the parens around - ;; "gnu" would be superfluous if it's a declarator. Shift the - ;; type one step backward. - (c-fdoc-shift-type-backward))) ! ;; Found no identifier. (if backup-at-type (progn --- 7058,7084 ---- ;; declaration. (throw 'at-decl-or-cast t)) ! (when (and got-parens ! (not got-prefix) ! ;; (not got-suffix-after-parens) ! (or backup-at-type ! maybe-typeless ! backup-maybe-typeless ! (eq at-decl-or-cast t) ! (save-excursion ! (goto-char name-start) ! (not (memq (c-forward-type) '(nil maybe)))))) ! ;; Got a declaration of the form "foo bar (gnu);" or "bar ! ;; (gnu);" where we've recognized "bar" as the type and "gnu" ! ;; as the declarator. In this case it's however more likely ! ;; that "bar" is the declarator and "gnu" a function argument ! ;; or initializer (if `c-recognize-paren-inits' is set), ! ;; since the parens around "gnu" would be superfluous if it's ! ;; a declarator. Shift the type one step backward. ! (c-fdoc-shift-type-backward))) + ;; Found no identifier. (if backup-at-type (progn > -Ivan -- Alan Mackenzie (Nuremberg, Germany).