[cfe-dev] Help with parsing C++ member-declarator
John McCall via cfe-dev
cfe-dev at lists.llvm.org
Wed Feb 21 20:53:47 PST 2018
> On Feb 7, 2018, at 10:17 AM, Jan Korous via cfe-dev <cfe-dev at lists.llvm.org> 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.
More information about the cfe-dev
mailing list