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

Kaelyn Uhrain rikka at google.com
Mon Nov 4 10:59:35 PST 2013


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()) {
+        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 '>'?}}
+}
+}





More information about the cfe-commits mailing list