[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: cc-mode uniform initialization support
From: |
Daniel Colascione |
Subject: |
Re: cc-mode uniform initialization support |
Date: |
Sat, 29 Aug 2015 17:54:58 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 |
On 08/20/2015 09:49 AM, Alan Mackenzie wrote:
> Hello, Daniel.
>
> On Wed, Aug 19, 2015 at 11:36:11AM -0700, Daniel Colascione wrote:
>> Recent versions of C++ support using {} to indicate an initialization
>> value. For example,
>
>> 1 int foo{5};
>> 2 int bar = {5};
>> 3 mumble_t mumble{
>> 4 foo,
>> 5 bar
>> 6 };
>> 7 return {mumble, foo}; // Type inferred from function declaration
>
> Yes.
>
>> Working with code written in this style is a nightmare right now because
>> cc-mode recognizes line 4 as defun-block-intro, leading to line 5 being
>> indented spuriously, since cc-mode thinks it's a statement continuation.
>> In reality, the construct starting at line 3 is a brace list, but
>> there's no syntactic clue to tell us that.
>
> How about the fact that there's no argument list (in parens)? Is that
> not sufficient to distinguish a brace list from a defun?
I don't think so. In the _same_ codebase, we have code that looks like this:
SCOPE_EXIT {
statement1,
statement1_cont;
statement2;
};
and
foo("foo", something{
item1,
item2});
Lots of codebases have SCOPE_EXIT-like things: the Linux kernel, for
example, has a bunch of custom LIST_FOREACH-like macros, so we can't
just check whether the word before the "{" is a keyword. The check for
whitespace before the "{" in my patch is a really hacky heuristic for
distinguishing the two cases. It works for the coding style I work with,
but it's not very good in general.
It's unfortunate that C++ overloaded "{" this way, since it makes it
hard to locally determine what's going on syntactically.
How about these rules? We'll assume we have a brace-list if:
1) we see "({" outside a macro definition, as in "foo({bar,qux})", or
2) we see a "{" preceded by "return", as in "return {1,2}" (say, in a
function declared to return std::pair<int,int>), or
3) we see a "{" preceded by a ",", as in "foo(foo, {bar})" (do we need
to look for operators generally?), or
4) we see a "{" preceded by an identifier not in ALL CAPS.
---
Do we need a separate c++11-mode so users can choose between c++-mode
with the old heuristics and the new one with the hacks I've described?
#1 and #4 might be controversial.
>> (We can, of course, look for an "=", but an "=" is no longer required
>> for a brace list.)
>
>> I don't see a way around needing to use awful heuristics to distinguish
>> the cases. Does anyone have a better idea? Keep in mind that code like
>> this is common too:
>
>> foo({
>> abc,
>> def
>> });
>
>> And plenty of people define macros that accept blocks:
>
>> MY_FOREACH {
>> statement1;
>> statement2;
>> }
>
> I've had a look at your patch, and after correcting it (so that at the
> indicated lines, the result of the `looking-at' is returned rather than
> the result of `backward-char' (which is nil)), tried it out. It does
> indeed appear to work on the example code you gave.
>
> However, it gives lots of errors in the test suite, including in some
> C++ test files (namely decls-15.cc, inexprstat-2.cc, inher-9.cc), so it
> needs some refinement. There are also a few niggly details where the
> patch isn't quite correct, but they should be easy enough to correct.
Thanks.
>
signature.asc
Description: OpenPGP digital signature