r194002 - Try to correct a mistyped "-" or ">" to "->" for some C++ cases.

Richard Smith richard at metafoo.co.uk
Mon Nov 4 18:37:13 PST 2013


On 4 Nov 2013 11:05, "Kaelyn Uhrain" <rikka at google.com> wrote:
>
> Author: rikka
> Date: Mon Nov  4 12:59:34 2013
> New Revision: 194002
>
> URL: http://llvm.org/viewvc/llvm-project?rev=194002&view=rev
> Log:
> Try to correct a mistyped "-" or ">" to "->" for some C++ cases.
>
> Similar C code isn't caught as it seems to hit a different code path.
> Also, as the check is only done for record pointers, cases involving
> an overloaded operator-> are not handled either. Note that the reason
> this check is done in the parser instead of Sema is not related to
> having enough knowledge about the current state as it is about being
> able to fix up the parser's state to be able to recover and traverse the
> correct code paths.
>
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>     cfe/trunk/lib/Parse/ParseExpr.cpp
>     cfe/trunk/test/SemaCXX/member-expr.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=194002&r1=194001&r2=194002&view=diff
>
==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Nov  4
12:59:34 2013
> @@ -499,6 +499,9 @@ def ext_abstract_pack_declarator_parens
>  def err_function_is_not_record : Error<
>    "unexpected '%select{.|->}0' in function call; perhaps remove the "
>    "'%select{.|->}0'?">;
> +def err_mistyped_arrow_in_member_access : Error<
> +  "use of undeclared identifier %0; did you mean '->' instead of "
> +  "'%select{-|>}1'?">;
>
>  // C++ derived classes
>  def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=194002&r1=194001&r2=194002&view=diff
>
==============================================================================
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Nov  4 12:59:34 2013
> @@ -166,6 +166,46 @@ ExprResult Parser::ParseAssignmentExpres
>    ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,
>                                         /*isAddressOfOperand=*/false,
>                                         isTypeCast);
> +
> +  // Check for a possible typo of "-" or ">" instead of "->" after a
> +  // pointer to a struct or class, while recovery is still possible.
> +  if (LHS.isUsable() && (Tok.is(tok::minus) || Tok.is(tok::greater))) {
> +    QualType LHSType = LHS.get()->getType();
> +    const RecordType *Pointee =
> +        LHSType->isPointerType()
> +            ? LHSType->getPointeeType()->getAsStructureType()
> +            : 0;
> +    const RecordDecl *RD = Pointee ? Pointee->getDecl() : 0;
> +    const Token &NextTok = NextToken();
> +    if (RD && NextTok.is(tok::identifier)) {
> +      UnqualifiedId Name;
> +      CXXScopeSpec ScopeSpec;
> +      SourceLocation TemplateKWLoc;
> +      NoTypoCorrectionCCC NoTCValidator;
> +      Name.setIdentifier(NextTok.getIdentifierInfo(),
NextTok.getLocation());
> +      Sema::SFINAETrap Trap(Actions);
> +      ExprResult Res =
> +          Actions.ActOnIdExpression(getCurScope(), ScopeSpec,
TemplateKWLoc,
> +                                    Name, false, false, &NoTCValidator);
> +      if (Res.isInvalid()) {

What happens if the next token is ( or :: or similar, and this identifier
is not an id-expression by itself? For instance, p-f(x) might find f by adl.

Also, in the case where this succeeds, we should annotate the produced
expression onto the token stream to avoid reparsing it later.

> +        Token OpTok = Tok;
> +        Tok.setKind(tok::arrow);
> +        PP.EnableBacktrackAtThisPos();
> +        Res = ParsePostfixExpressionSuffix(LHS);
> +        if (Res.isUsable()) {
> +          LHS = Res;
> +          PP.CommitBacktrackedTokens();
> +          Diag(OpTok, diag::err_mistyped_arrow_in_member_access)
> +              << NextTok.getIdentifierInfo() << OpTok.is(tok::greater)
> +              << FixItHint::CreateReplacement(OpTok.getLocation(), "->");
> +        } else {
> +          Tok = OpTok;
> +          PP.Backtrack();
> +        }
> +      }
> +    }
> +  }
> +
>    return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
>  }
>
>
> Modified: cfe/trunk/test/SemaCXX/member-expr.cpp
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=194002&r1=194001&r2=194002&view=diff
>
==============================================================================
> --- cfe/trunk/test/SemaCXX/member-expr.cpp (original)
> +++ cfe/trunk/test/SemaCXX/member-expr.cpp Mon Nov  4 12:59:34 2013
> @@ -224,3 +224,16 @@ namespace pr16676 {
>          .i;  // expected-error {{member reference type 'pr16676::S *' is
a pointer; maybe you meant to use '->'}}
>    }
>  }
> +
> +namespace PR9054 {
> +struct Foo {
> +  void bar(int);
> +  int fiz;
> +};
> +
> +int test(struct Foo *foo) {
> +  foo-bar(5);  // expected-error {{use of undeclared identifier 'bar';
did you mean '->' instead of '-'?}}
> +  foo>baz(4);  // expected-error-re {{use of undeclared identifier
'baz'$}}
> +  return foo>fiz;  // expected-error {{use of undeclared identifier
'fiz'; did you mean '->' instead of '>'?}}
> +}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131104/daf4a3ca/attachment.html>


More information about the cfe-commits mailing list