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