<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>