[cfe-commits] r58913 - in /cfe/trunk: Driver/PrintParserCallbacks.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h lib/Parse/MinimalAction.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTentative.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp test/Lexer/cxx0x_keyword.cpp

Douglas Gregor dgregor at apple.com
Fri Nov 14 13:01:43 PST 2008


On Nov 14, 2008, at 3:30 PM, Argiris Kirtzidis wrote:

> Hi Doug,
>
> Douglas Gregor wrote:
>>
>>> +  /// isTokenUnqualifiedId - True if token is the start of C++  
>>> unqualified-id
>>> +  /// or an identifier in C.
>>> +  ///
>>> +  ///       unqualified-id:
>>> +  ///         identifier
>>> +  /// [C++]   operator-function-id
>>> +  /// [C++]   conversion-function-id
>>> +  /// [C++]   '~' class-name
>>> +  /// [C++]   template-id      [TODO]
>>> +  ///
>>> +  bool isTokenUnqualifiedId() const {
>>> +    return Tok.is(tok::identifier)  ||   // identifier or  
>>> template-id
>>> +           Tok.is(tok::kw_operator) ||   // operator/conversion- 
>>> function-id or
>>> +                                         // template-id
>>> +           (Tok.is(tok::tilde) && getLang().CPlusPlus); // '~'  
>>> class-name
>>> +  }
>>
>> This works because a qualified-id will already have been annotated,  
>> so the token we see would be a annot_cxxscope or annot_qualtype,  
>> right?
>
> Yes, but isTokenUnqualifiedId was supposed to be used at  
> ParseDirectDeclarator but after your changes in that function I  
> didn't make use of it. I'll remove it, if there's a need for it we  
> can bring it in again.

Even better! :)

>
>>
>>> +      // If the next token is the name of the class type that the  
>>> C++ scope
>>> +      // denotes, followed by a '(', then this is a constructor  
>>> declaration.
>>> +      // We're done with the decl-specifiers.
>>> +      if  
>>> (Actions.isCurrentClassName(*NextToken().getIdentifierInfo(),
>>> +                                     CurScope, &SS) &&
>>> +          GetLookAheadToken(2).is(tok::l_paren))
>>> +        goto DoneWithDeclSpec;
>>>
>>
>> This won't parse constructors like
>>
>>    ((C::C))(int, float) {
>>    }
>>
>> properly, right? I think the '&&  
>> GetLookAheadToken(2).is(tok::l_paren)' needs to be removed.
>
> A '(' means parsing of declaration specifiers is finished,  
> Parser::ParseDeclarationSpecifiers will exit and this part of the  
> code will not be reached.
> You are doing a similar thing under "case tok::identifier":
>
>     // C++: If the identifier is actually the name of the class type
>     // being defined and the next token is a '(', then this is a
>     // constructor declaration. We're done with the decl-specifiers
>     // and will treat this token as an identifier.
>     if (getLang().CPlusPlus &&
>         CurScope->isCXXClassScope() &&
>         Actions.isCurrentClassName(*Tok.getIdentifierInfo(),  
> CurScope) &&
>         NextToken().getKind() == tok::l_paren)
>       goto DoneWithDeclSpec;

Oh, I understand now. In the case of something like ((C::C)), we know  
we're not still parsing decl-specifiers, so we don't hit this case.  
Thanks!

> As a sidenote, "C::C" is messy stuff, since whether it's the  
> constructor or the injected class-name depends on the context  
> (ambiguous syntax in C++ ? what a surprise..)
> I didn't take a crack at it yet, so out-of-line constructors are  
> currently broken.

Ick. Well, C::C only refers to the constructor if we're parsing a  
declarator; everywhere else, it's a type, so I don't think it'll be  
that tricky to deal with.

	- Doug



More information about the cfe-commits mailing list