<p dir="ltr"><br>
On 4 Nov 2013 11:05, "Kaelyn Uhrain" <<a href="mailto:rikka@google.com">rikka@google.com</a>> wrote:<br>
><br>
> Author: rikka<br>
> Date: Mon Nov  4 12:59:34 2013<br>
> New Revision: 194002<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194002&view=rev">http://llvm.org/viewvc/llvm-project?rev=194002&view=rev</a><br>
> Log:<br>
> Try to correct a mistyped "-" or ">" to "->" for some C++ cases.<br>
><br>
> Similar C code isn't caught as it seems to hit a different code path.<br>
> Also, as the check is only done for record pointers, cases involving<br>
> an overloaded operator-> are not handled either. Note that the reason<br>
> this check is done in the parser instead of Sema is not related to<br>
> having enough knowledge about the current state as it is about being<br>
> able to fix up the parser's state to be able to recover and traverse the<br>
> correct code paths.<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
>     cfe/trunk/lib/Parse/ParseExpr.cpp<br>
>     cfe/trunk/test/SemaCXX/member-expr.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=194002&r1=194001&r2=194002&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=194002&r1=194001&r2=194002&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Nov  4 12:59:34 2013<br>
> @@ -499,6 +499,9 @@ def ext_abstract_pack_declarator_parens<br>
>  def err_function_is_not_record : Error<<br>
>    "unexpected '%select{.|->}0' in function call; perhaps remove the "<br>
>    "'%select{.|->}0'?">;<br>
> +def err_mistyped_arrow_in_member_access : Error<<br>
> +  "use of undeclared identifier %0; did you mean '->' instead of "<br>
> +  "'%select{-|>}1'?">;<br>
><br>
>  // C++ derived classes<br>
>  def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=194002&r1=194001&r2=194002&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=194002&r1=194001&r2=194002&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Nov  4 12:59:34 2013<br>
> @@ -166,6 +166,46 @@ ExprResult Parser::ParseAssignmentExpres<br>
>    ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,<br>
>                                         /*isAddressOfOperand=*/false,<br>
>                                         isTypeCast);<br>
> +<br>
> +  // Check for a possible typo of "-" or ">" instead of "->" after a<br>
> +  // pointer to a struct or class, while recovery is still possible.<br>
> +  if (LHS.isUsable() && (Tok.is(tok::minus) || Tok.is(tok::greater))) {<br>
> +    QualType LHSType = LHS.get()->getType();<br>
> +    const RecordType *Pointee =<br>
> +        LHSType->isPointerType()<br>
> +            ? LHSType->getPointeeType()->getAsStructureType()<br>
> +            : 0;<br>
> +    const RecordDecl *RD = Pointee ? Pointee->getDecl() : 0;<br>
> +    const Token &NextTok = NextToken();<br>
> +    if (RD && NextTok.is(tok::identifier)) {<br>
> +      UnqualifiedId Name;<br>
> +      CXXScopeSpec ScopeSpec;<br>
> +      SourceLocation TemplateKWLoc;<br>
> +      NoTypoCorrectionCCC NoTCValidator;<br>
> +      Name.setIdentifier(NextTok.getIdentifierInfo(), NextTok.getLocation());<br>
> +      Sema::SFINAETrap Trap(Actions);<br>
> +      ExprResult Res =<br>
> +          Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,<br>
> +                                    Name, false, false, &NoTCValidator);<br>
> +      if (Res.isInvalid()) {</p>
<p dir="ltr">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.</p>
<p dir="ltr">Also, in the case where this succeeds, we should annotate the produced expression onto the token stream to avoid reparsing it later.</p>
<p dir="ltr">> +        Token OpTok = Tok;<br>
> +        Tok.setKind(tok::arrow);<br>
> +        PP.EnableBacktrackAtThisPos();<br>
> +        Res = ParsePostfixExpressionSuffix(LHS);<br>
> +        if (Res.isUsable()) {<br>
> +          LHS = Res;<br>
> +          PP.CommitBacktrackedTokens();<br>
> +          Diag(OpTok, diag::err_mistyped_arrow_in_member_access)<br>
> +              << NextTok.getIdentifierInfo() << OpTok.is(tok::greater)<br>
> +              << FixItHint::CreateReplacement(OpTok.getLocation(), "->");<br>
> +        } else {<br>
> +          Tok = OpTok;<br>
> +          PP.Backtrack();<br>
> +        }<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +<br>
>    return ParseRHSOfBinaryExpression(LHS, prec::Assignment);<br>
>  }<br>
><br>
><br>
> Modified: cfe/trunk/test/SemaCXX/member-expr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=194002&r1=194001&r2=194002&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=194002&r1=194001&r2=194002&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/member-expr.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/member-expr.cpp Mon Nov  4 12:59:34 2013<br>
> @@ -224,3 +224,16 @@ namespace pr16676 {<br>
>          .i;  // expected-error {{member reference type 'pr16676::S *' is a pointer; maybe you meant to use '->'}}<br>
>    }<br>
>  }<br>
> +<br>
> +namespace PR9054 {<br>
> +struct Foo {<br>
> +  void bar(int);<br>
> +  int fiz;<br>
> +};<br>
> +<br>
> +int test(struct Foo *foo) {<br>
> +  foo-bar(5);  // expected-error {{use of undeclared identifier 'bar'; did you mean '->' instead of '-'?}}<br>
> +  foo>baz(4);  // expected-error-re {{use of undeclared identifier 'baz'$}}<br>
> +  return foo>fiz;  // expected-error {{use of undeclared identifier 'fiz'; did you mean '->' instead of '>'?}}<br>
> +}<br>
> +}<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</p>