Help with parsing C++ member-declarator

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Help with parsing C++ member-declarator

Dennis Luehring via cfe-dev
Hi all,

I would like to ask for help with Parser. My goal is to detect grammatically invalid order of *override* and *noexcept* keywords in parser and suggest a fixit.

C++ grammar of member-declarator allows virt-specifier-seq (e. g. override) only after declarator (which contains exception-specification - e. g. noexcept).

For this code:

struct Base { virtual void foo(); };
struct Derived : Base { virtual void foo() override noexcept; };

we currently display this error:

exp.cpp:2:52: error: expected ';' at end of declaration list

from which the issue is not really obvious.

Current implementation works like this.

The starting point is ParseCXXMemberDeclaratorBeforeInitializer() which calls (in this order):
1. ParseFunctionDeclarator() which parses all of these
    cv-qualifier-seq,
    ref-qualifier,
    exception-specification,
    attribute-specifier-seq,
    exception-specification,
    dynamic-exception-specification,
    noexcept-specification

2. ParseOptionalCXX11VirtSpecifierSeq() which parses
    virt-specifier-seq

The call graph looks like this:

ParseCXXMemberDeclaratorBeforeInitializer()
    ParseDeclarator()
        ParseDeclaratorInternal( &ParseDirectDeclarator ) // pointer to method as an argument
            ParseDirectDeclarator()
                ParseFunctionDeclarator()

ParseCXXMemberDeclaratorBeforeInitializer()
    ParseOptionalCXX11VirtSpecifierSeq()

There's also this related FIXME:

ParseDecl.cpp:6028
      // FIXME: Accept these components in any order, and produce fixits to
      // correct the order if the user gets it wrong. Ideally we should deal
      // with the pure-specifier in the same way.

What do you guys recommend as the best approach here? I would expect some refactoring of relevant methods and then just a small if block detecting the wrong order of keywords, outputting diagnostics and fixit and swapping those tokens. I am still just getting familiar with the codebase and would appreciate some guidance.

Thank you.

Best,

Jan
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Help with parsing C++ member-declarator

Dennis Luehring via cfe-dev
> On Feb 7, 2018, at 10:17 AM, Jan Korous via cfe-dev <[hidden email]> wrote:
>
> Hi all,
>
> I would like to ask for help with Parser. My goal is to detect grammatically invalid order of *override* and *noexcept* keywords in parser and suggest a fixit.
>
> C++ grammar of member-declarator allows virt-specifier-seq (e. g. override) only after declarator (which contains exception-specification - e. g. noexcept).
>
> For this code:
>
> struct Base { virtual void foo(); };
> struct Derived : Base { virtual void foo() override noexcept; };
>
> we currently display this error:
>
> exp.cpp:2:52: error: expected ';' at end of declaration list
>
> from which the issue is not really obvious.
>
> Current implementation works like this.
>
> The starting point is ParseCXXMemberDeclaratorBeforeInitializer() which calls (in this order):
> 1. ParseFunctionDeclarator() which parses all of these
>    cv-qualifier-seq,
>    ref-qualifier,
>    exception-specification,
>    attribute-specifier-seq,
>    exception-specification,
>    dynamic-exception-specification,
>    noexcept-specification
>
> 2. ParseOptionalCXX11VirtSpecifierSeq() which parses
>    virt-specifier-seq
>
> The call graph looks like this:
>
> ParseCXXMemberDeclaratorBeforeInitializer()
>    ParseDeclarator()
>        ParseDeclaratorInternal( &ParseDirectDeclarator ) // pointer to method as an argument
>            ParseDirectDeclarator()
>                ParseFunctionDeclarator()
>
> ParseCXXMemberDeclaratorBeforeInitializer()
>    ParseOptionalCXX11VirtSpecifierSeq()
>
> There's also this related FIXME:
>
> ParseDecl.cpp:6028
>      // FIXME: Accept these components in any order, and produce fixits to
>      // correct the order if the user gets it wrong. Ideally we should deal
>      // with the pure-specifier in the same way.
>
> What do you guys recommend as the best approach here? I would expect some refactoring of relevant methods and then just a small if block detecting the wrong order of keywords, outputting diagnostics and fixit and swapping those tokens. I am still just getting familiar with the codebase and would appreciate some guidance.

I would just make a loop that looks for all the specifications at once and stops when it sees something it doesn't recognize.  Keep an enum that tracks where you are in the sequence and use that diagnose out-of-order specifications.  Remember to also diagnose duplicates.

John.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev