diff options
author | Kaelyn Uhrain <rikka@google.com> | 2012-04-25 19:49:54 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2012-04-25 19:49:54 +0000 |
commit | 2b90f7637e846ea555dedac14e7f5065d85c5d3b (patch) | |
tree | 1b958a95d03853904729c05e6423027752e9488f /lib/Sema/SemaExprMember.cpp | |
parent | ad579916bc402cf617793e94770bab78e9bdaec8 (diff) |
Add an error message with fixit hint for changing '.' to '->'.
This is mainly for attempting to recover in cases where a class provides
a custom operator-> and a '.' was accidentally used instead of '->' when
accessing a member of the object returned by the current object's
operator->.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155580 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 01d5fc6584..81aba6ac0e 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -813,8 +813,9 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, - bool SuppressQualifierCheck) { + const TemplateArgumentListInfo *TemplateArgs, + bool SuppressQualifierCheck, + ActOnMemberAccessExtraArgs *ExtraArgs) { QualType BaseType = BaseExprType; if (IsArrow) { assert(BaseType->isPointerType()); @@ -835,6 +836,32 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, ? computeDeclContext(SS, false) : BaseType->getAs<RecordType>()->getDecl()); + if (ExtraArgs) { + ExprResult RetryExpr; + if (!IsArrow && BaseExpr) { + SFINAETrap Trap(*this); + ParsedType ObjectType; + bool MayBePseudoDestructor = false; + RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr, + OpLoc, tok::arrow, ObjectType, + MayBePseudoDestructor); + if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) { + CXXScopeSpec TempSS(SS); + RetryExpr = ActOnMemberAccessExpr( + ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS, + TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl, + ExtraArgs->HasTrailingLParen); + } + if (Trap.hasErrorOccurred()) + RetryExpr = ExprError(); + } + if (RetryExpr.isUsable()) { + Diag(OpLoc, diag::err_no_member_overloaded_arrow) + << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->"); + return RetryExpr; + } + } + Diag(R.getNameLoc(), diag::err_no_member) << MemberName << DC << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange()); @@ -1506,9 +1533,11 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, return move(Result); } + ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen}; Result = BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc, - FirstQualifierInScope, R, TemplateArgs); + FirstQualifierInScope, R, TemplateArgs, + false, &ExtraArgs); } return move(Result); |