[cfe-dev] [PATCH]: Parsing for C++ classes

Argiris Kirtzidis akyrtzi at gmail.com
Sat Jun 21 08:23:00 PDT 2008


Eli Friedman wrote:
> A couple more potential issues that I found while re-reading the patch:
> +    bool isInstField = (DS.getStorageClassSpec() ==
> DeclSpec::SCS_unspecified &&
> +                        !DeclaratorInfo.isFunctionDeclarator());
>
> This check isn't reliable. Simple example: "typedef int func(); class
> C {func a,b;};".
>   

Ah, good find!
How about adding a Action::isFunctionTypeDeclarator for the parser to 
get this kind of information:

>     // typedef int func();
>     // class C {func a,b;};
>     bool isTypedefFunc = (!DeclaratorInfo.isFunctionDeclarator() &&
>                           
> Actions.isFunctionTypeDeclarator(DeclaratorInfo, CurScope));
>     bool isInstField = (DS.getStorageClassSpec() == 
> DeclSpec::SCS_unspecified &&
>                         !DeclaratorInfo.isFunctionDeclarator() &&
>                         !isTypedefFunc);

Do you have some other suggestion ?

> +  typedef std::list<LexedInlineMethod> LexedInlineMethodsTy;
> +  /// LexedInlineMethods - During parsing of a C++ class, its inline method
> +  /// definitions and the inline method definitions of its nested classes are
> +  /// lexed and stored here.
> +  LexedInlineMethodsTy LexedInlineMethods;
> [...]
> +  if (!(CurScope->getFlags() & Scope::CXXClassScope)) {
> +    // We are no longer inside a C++ class. This class and its nested classes
> +    // are complete and we can parse the lexed inline method definitions.
> +    for (LexedInlineMethodsTy::iterator I = LexedInlineMethods.begin();
> +         I != LexedInlineMethods.end(); ++I) {
>
> This isn't quite right; consider the following:
> class X {
>
>   int outer() {
>    static int b;
>    class C {
>      public:
>      int inner() {
>        return b;
>      }
>    } r;
>    return r.inner();
>   };
>
>   int other() {return b;}
>
>   int x;
> };
>
> With the current code, at least according to my reading, first X gets
> parsed, then we start parsing outer, then we finish parsing class C,
> then we attempt to start parsing outer again, then bad things happen.
>
> I'd suggest allocating LexedInlineMethods in
> ParseCXXMemberSpecification, rather than making it a member of Parser.
>   

Ok, I now use a "stack<LexedInlineMethodsTy>" as member of Parser and 
ParseCXXMemberSpecification pushes a new LexedInlineMethodsTy container 
for each non-nested class.
ParseInlineMethodDef pushes the new method to the top container.

Thanks for the catch!


-Argiris



More information about the cfe-dev mailing list