]> granicus.if.org Git - clang/commitdiff
Provide fix-it for '.' <-> '->' for Objective-C ivar/property access.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 28 Jun 2011 00:00:52 +0000 (00:00 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 28 Jun 2011 00:00:52 +0000 (00:00 +0000)
// rdar://7811841

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133970 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaExprMember.cpp
lib/Sema/SemaExprObjC.cpp
test/FixIt/fixit-objc.m

index 22848bcb35d339e241631624d3673d5255a97437..3134bdd40658f06decde8d5a8de5b17df1fc3061 100644 (file)
@@ -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<
index d38667253df422107478a17b89ea9ba657416207..724e1ea29cda6eac024c341ec21bb3739aa0488c 100644 (file)
@@ -5056,6 +5056,7 @@ public:
   ExprResult
   HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
                             Expr *BaseExpr,
+                            SourceLocation OpLoc,
                             DeclarationName MemberName,
                             SourceLocation MemberLoc,
                             SourceLocation SuperLoc, QualType SuperType,
index 082691ffed5b14a9fce076dbca125a40df31040c..950976820512d14244abed242c445cf621d044bd 100644 (file)
@@ -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);
   }
 
index 84ac897b376d7cc3fcb60c4f00c80c27c10f32ee..80d3a7451de8d4d90f2162513b2bf87cf734ec1d 100644 (file)
@@ -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<ObjCPropertyDecl>();
     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);
         }
index bf704c66a0275679e834ee26fd0b2bc3df03612b..2e8bfaea6aa3a69ff2f59fe241e90a9cae154b70 100644 (file)
@@ -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?}}
+