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
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 01d5fc6..81aba6a 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -813,8 +813,9 @@
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 @@
? 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 @@
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);