From 6326e05fe8c2ff92b65b4759a91e45fad5ef886f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 28 Jun 2011 00:00:52 +0000 Subject: [PATCH] Provide fix-it for '.' <-> '->' for Objective-C ivar/property access. // rdar://7811841 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133970 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ include/clang/Sema/Sema.h | 1 + lib/Sema/SemaExprMember.cpp | 10 +++++++++- lib/Sema/SemaExprObjC.cpp | 15 ++++++++++++--- test/FixIt/fixit-objc.m | 14 ++++++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 22848bcb35..3134bdd406 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4320,6 +4320,11 @@ def err_typecheck_member_reference_ivar_suggest : Error< "%0 does not have a member named %1; did you mean %2?">; def err_property_not_found_suggest : Error< "property %0 not found on object of type %1; did you mean %2?">; +def err_ivar_access_using_property_syntax_suggest : Error< + "property %0 not found on object of type %1; did you mean to access ivar %2?">; +def err_property_found_suggest : Error< + "property %0 found on object of type %1; did you mean to access " + "it with the \".\" operator?">; def err_undef_interface_suggest : Error< "cannot find interface declaration for %0; did you mean %1?">; def warn_undef_interface_suggest : Warning< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index d38667253d..724e1ea29c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5056,6 +5056,7 @@ public: ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, + SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 082691ffed..9509768205 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -1080,6 +1080,13 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, Diag(IV->getLocation(), diag::note_previous_decl) << IV->getDeclName(); } else { + if (IsArrow && IDecl->FindPropertyDeclaration(Member)) { + Diag(MemberLoc, + diag::err_property_found_suggest) + << Member << BaseExpr.get()->getType() + << FixItHint::CreateReplacement(OpLoc, "."); + return ExprError(); + } Res.clear(); Res.setLookupName(Member); @@ -1284,7 +1291,8 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, } // Normal property access. - return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), MemberName, MemberLoc, + return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, + MemberName, MemberLoc, SourceLocation(), QualType(), false); } diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 84ac897b37..80d3a7451d 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -516,7 +516,8 @@ ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel, /// objective C interface. This is a property reference expression. ExprResult Sema:: HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, - Expr *BaseExpr, DeclarationName MemberName, + Expr *BaseExpr, SourceLocation OpLoc, + DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super) { @@ -672,7 +673,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, ObjCPropertyDecl *Property = Res.getAsSingle(); Diag(Property->getLocation(), diag::note_previous_decl) << Property->getDeclName(); - return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc, + return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, + TypoResult, MemberLoc, SuperLoc, SuperType, Super); } ObjCInterfaceDecl *ClassDeclared; @@ -690,6 +692,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } } + Diag(MemberLoc, + diag::err_ivar_access_using_property_syntax_suggest) + << MemberName << QualType(OPT, 0) << Ivar->getDeclName() + << FixItHint::CreateReplacement(OpLoc, "->"); + return ExprError(); } Diag(MemberLoc, diag::err_property_not_found) @@ -726,7 +733,9 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, T = Context.getObjCObjectPointerType(T); return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), - /*BaseExpr*/0, &propertyName, + /*BaseExpr*/0, + SourceLocation()/*OpLoc*/, + &propertyName, propertyNameLoc, receiverNameLoc, T, true); } diff --git a/test/FixIt/fixit-objc.m b/test/FixIt/fixit-objc.m index bf704c66a0..2e8bfaea6a 100644 --- a/test/FixIt/fixit-objc.m +++ b/test/FixIt/fixit-objc.m @@ -39,3 +39,17 @@ void f(Test *t) { [t test:@"Foo"]]; // expected-error{{extraneous ']' before ';'}} g(@"Foo")); // expected-error{{extraneous ')' before ';'}} } + +// rdar://7861841 +@interface Radar7861841 { +@public + int x; +} + +@property (assign) int y; +@end + +int f0(Radar7861841 *a) { return a.x; } // expected-error {{property 'x' not found on object of type 'Radar7861841 *'; did you mean to access ivar 'x'}} + +int f1(Radar7861841 *a) { return a->y; } // expected-error {{property 'y' found on object of type 'Radar7861841 *'; did you mean to access it with the "." operator?}} + -- 2.40.0