r221736 - Have LookupMemberExprInRecord only call CorrectTypoDelayed, dropping the

Kaelyn Takata rikka at google.com
Tue Nov 11 15:26:58 PST 2014


Author: rikka
Date: Tue Nov 11 17:26:58 2014
New Revision: 221736

URL: http://llvm.org/viewvc/llvm-project?rev=221736&view=rev
Log:
Have LookupMemberExprInRecord only call CorrectTypoDelayed, dropping the
code for calling CorrectTypo.

Includes a needed fix for non-C++ code to not choke on TypoExprs (which
also resolves a TODO from r220698).

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprMember.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=221736&r1=221735&r2=221736&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 11 17:26:58 2014
@@ -8618,6 +8618,17 @@ QualType Sema::CheckAssignmentOperands(E
                                        QualType CompoundType) {
   assert(!LHSExpr->hasPlaceholderType(BuiltinType::PseudoObject));
 
+  if (!getLangOpts().CPlusPlus) {
+    // C cannot handle TypoExpr nodes on either side of n assignment because it
+    // doesn't handle dependent types properly, so make sure any TypoExprs have
+    // been dealt with before checking the operands.
+    ExprResult Res = CorrectDelayedTyposInExpr(LHSExpr);
+    Expr *NewLHS = Res.isInvalid() ? LHSExpr : Res.get();
+    Res = CorrectDelayedTyposInExpr(RHS);
+    if (!Res.isInvalid() && (Res.get() != RHS.get() || NewLHS != LHSExpr))
+      return CheckAssignmentOperands(NewLHS, Res, Loc, CompoundType);
+  }
+
   // Verify that LHS is a modifiable lvalue, and emit error if not.
   if (CheckForModifiableLvalue(LHSExpr, Loc, *this))
     return QualType();

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=221736&r1=221735&r2=221736&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Tue Nov 11 17:26:58 2014
@@ -585,7 +585,7 @@ static bool LookupMemberExprInRecord(Sem
                                      const RecordType *RTy,
                                      SourceLocation OpLoc, bool IsArrow,
                                      CXXScopeSpec &SS, bool HasTemplateArgs,
-                                     TypoExpr **TE = nullptr) {
+                                     TypoExpr *&TE) {
   SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
   RecordDecl *RDecl = RTy->getDecl();
   if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&
@@ -630,74 +630,37 @@ static bool LookupMemberExprInRecord(Sem
   if (!R.empty())
     return false;
 
-  if (TE && SemaRef.getLangOpts().CPlusPlus) {
-    DeclarationName Typo = R.getLookupName();
-    SourceLocation TypoLoc = R.getNameLoc();
-    // TODO: C cannot handle TypoExpr nodes because the C code paths do not know
-    // what to do with dependent types e.g. on the LHS of an assigment.
-    *TE = SemaRef.CorrectTypoDelayed(
-        R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
-        llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
-        [=, &SemaRef](const TypoCorrection &TC) {
-          if (TC) {
-            assert(!TC.isKeyword() &&
-                   "Got a keyword as a correction for a member!");
-            bool DroppedSpecifier =
-                TC.WillReplaceSpecifier() &&
-                Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
-            SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
-                                         << Typo << DC << DroppedSpecifier
-                                         << SS.getRange());
-          } else {
-            SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC
-                                                       << BaseRange;
-          }
-        },
-        [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
-          R.clear();  // Ensure there's no decls lingering in the shared state.
-          R.suppressDiagnostics();
-          R.setLookupName(TC.getCorrection());
-          for (NamedDecl *ND : TC)
-            R.addDecl(ND);
-          R.resolveKind();
-          return SemaRef.BuildMemberReferenceExpr(
-              BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS,
-              SourceLocation(), nullptr, R, nullptr);
-        },
-        Sema::CTK_ErrorRecovery, DC);
-    R.clear();
-    return false;
-  }
-
-  // We didn't find anything with the given name, so try to correct
-  // for typos.
-  DeclarationName Name = R.getLookupName();
-  TypoCorrection Corrected = SemaRef.CorrectTypo(
+  DeclarationName Typo = R.getLookupName();
+  SourceLocation TypoLoc = R.getNameLoc();
+  TE = SemaRef.CorrectTypoDelayed(
       R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
       llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
+      [=, &SemaRef](const TypoCorrection &TC) {
+        if (TC) {
+          assert(!TC.isKeyword() &&
+                 "Got a keyword as a correction for a member!");
+          bool DroppedSpecifier =
+              TC.WillReplaceSpecifier() &&
+              Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
+          SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
+                                       << Typo << DC << DroppedSpecifier
+                                       << SS.getRange());
+        } else {
+          SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange;
+        }
+      },
+      [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
+        R.clear(); // Ensure there's no decls lingering in the shared state.
+        R.suppressDiagnostics();
+        R.setLookupName(TC.getCorrection());
+        for (NamedDecl *ND : TC)
+          R.addDecl(ND);
+        R.resolveKind();
+        return SemaRef.BuildMemberReferenceExpr(
+            BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(),
+            nullptr, R, nullptr);
+      },
       Sema::CTK_ErrorRecovery, DC);
-  R.clear();
-  if (Corrected.isResolved() && !Corrected.isKeyword()) {
-    R.setLookupName(Corrected.getCorrection());
-    for (TypoCorrection::decl_iterator DI = Corrected.begin(),
-                                       DIEnd = Corrected.end();
-         DI != DIEnd; ++DI) {
-      R.addDecl(*DI);
-    }
-    R.resolveKind();
-
-    // If we're typo-correcting to an overloaded name, we don't yet have enough
-    // information to do overload resolution, so we don't know which previous
-    // declaration to point to.
-    if (Corrected.isOverloaded())
-      Corrected.setCorrectionDecl(nullptr);
-    bool DroppedSpecifier =
-        Corrected.WillReplaceSpecifier() &&
-        Name.getAsString() == Corrected.getAsString(SemaRef.getLangOpts());
-    SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_no_member_suggest)
-                                        << Name << DC << DroppedSpecifier
-                                        << SS.getRange());
-  }
 
   return false;
 }
@@ -727,12 +690,15 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
 
   // Implicit member accesses.
   if (!Base) {
+    TypoExpr *TE = nullptr;
     QualType RecordTy = BaseType;
     if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
     if (LookupMemberExprInRecord(*this, R, nullptr,
                                  RecordTy->getAs<RecordType>(), OpLoc, IsArrow,
-                                 SS, TemplateArgs != nullptr))
+                                 SS, TemplateArgs != nullptr, TE))
       return ExprError();
+    if (TE)
+      return TE;
 
   // Explicit member accesses.
   } else {
@@ -1262,7 +1228,7 @@ static ExprResult LookupMemberExpr(Sema
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
     TypoExpr *TE = nullptr;
     if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy,
-                                 OpLoc, IsArrow, SS, HasTemplateArgs, &TE))
+                                 OpLoc, IsArrow, SS, HasTemplateArgs, TE))
       return ExprError();
 
     // Returning valid-but-null is how we indicate to the caller that





More information about the cfe-commits mailing list