]> granicus.if.org Git - clang/commitdiff
Fix a bug where a local variable named 'self' is causing
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 12 Jul 2011 17:16:56 +0000 (17:16 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 12 Jul 2011 17:16:56 +0000 (17:16 +0000)
implicit ivar accesses to go through the 'self' variable
rather than the real 'self' for the method. // rdar://9730771

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

include/clang/Sema/DeclSpec.h
include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaType.cpp
test/SemaObjC/self-declared-in-block.m

index e3bc5bff57bed03dfad29c7136c9688e508697bb..cbf47e8b050d50d0f813bf95a92d14ae02ae069e 100644 (file)
@@ -767,7 +767,9 @@ public:
     /// \brief A destructor name.
     IK_DestructorName,
     /// \brief A template-id, e.g., f<int>.
-    IK_TemplateId
+    IK_TemplateId,
+    /// \brief An implicit 'self' parameter
+    IK_ImplicitSelfParam
   } Kind;
 
   /// \brief Anonymous union that holds extra data associated with the
@@ -820,7 +822,7 @@ public:
   SourceLocation EndLocation;
   
   UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { }
-  
+
   /// \brief Do not use this copy constructor. It is temporary, and only
   /// exists because we are holding FieldDeclarators in a SmallVector when we
   /// don't actually need them.
@@ -847,6 +849,7 @@ public:
   
   /// \brief Determine what kind of name we have.
   IdKind getKind() const { return Kind; }
+  void setKind(IdKind kind) { Kind = kind; } 
   
   /// \brief Specify that this unqualified-id was parsed as an identifier.
   ///
index 54debed6978b076f340d2beb8839e929e83ebf64..263c1bd49ac9d7db6848c82323e11efdc678279a 100644 (file)
@@ -1605,6 +1605,8 @@ public:
     LookupRedeclarationWithLinkage,
     /// Look up the name of an Objective-C protocol.
     LookupObjCProtocolName,
+    /// Look up implicit 'self' parameter of an objective-c method.
+    LookupObjCImplicitSelfParam,
     /// \brief Look up any declaration with any name.
     LookupAnyName
   };
index 49c3f8a48f12062268b7babb7c3350cf65067bfa..c5caae279cb7acd016b9ada8fabe59123ca52a76 100644 (file)
@@ -2766,6 +2766,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
 
   switch (Name.getKind()) {
 
+  case UnqualifiedId::IK_ImplicitSelfParam:
   case UnqualifiedId::IK_Identifier:
     NameInfo.setName(Name.Identifier);
     NameInfo.setLoc(Name.StartLocation);
index e20ec40b6ab1b43830b352dfda77899d8b894072..62c163435c7a216daf9bc1b4b5e959abbf41008b 100644 (file)
@@ -4987,6 +4987,7 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
 
   switch (Name.getKind()) {
+  case UnqualifiedId::IK_ImplicitSelfParam:
   case UnqualifiedId::IK_Identifier:
   case UnqualifiedId::IK_OperatorFunctionId:
   case UnqualifiedId::IK_LiteralOperatorId:
index 9f91052e4cb9fc3250955a5f42aede32ea045efb..fa8721ce345c6a4049bef3aa407f6e262bdf566c 100644 (file)
@@ -1603,7 +1603,9 @@ ExprResult Sema::ActOnIdExpression(Scope *S,
 
   bool IvarLookupFollowUp = false;
   // Perform the required lookup.
-  LookupResult R(*this, NameInfo, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, 
+                 (Id.getKind() == UnqualifiedId::IK_ImplicitSelfParam) 
+                  ? LookupObjCImplicitSelfParam : LookupOrdinaryName);
   if (TemplateArgs) {
     // Lookup the template name again to correctly establish the context in
     // which it was found. This is really unfortunate as we already did the
@@ -1834,6 +1836,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
       IdentifierInfo &II = Context.Idents.get("self");
       UnqualifiedId SelfName;
       SelfName.setIdentifier(&II, SourceLocation());
+      SelfName.setKind(UnqualifiedId::IK_ImplicitSelfParam);
       CXXScopeSpec SelfScopeSpec;
       ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
                                               SelfName, false, false);
@@ -1845,27 +1848,6 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
         return ExprError();
 
       MarkDeclarationReferenced(Loc, IV);
-      Expr *base = SelfExpr.take();
-      base = base->IgnoreParenImpCasts();
-      if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(base)) {
-        const NamedDecl *ND = DE->getDecl();
-        if (!isa<ImplicitParamDecl>(ND)) {
-          // relax the rule such that it is allowed to have a shadow 'self'
-          // where stand-alone ivar can be found in this 'self' object. 
-          // This is to match gcc's behavior.
-          ObjCInterfaceDecl *selfIFace = 0;
-          if (const ObjCObjectPointerType *OPT =
-              base->getType()->getAsObjCInterfacePointerType())
-            selfIFace = OPT->getInterfaceDecl();
-          if (!selfIFace || 
-              !selfIFace->lookupInstanceVariable(IV->getIdentifier())) {
-            Diag(Loc, diag::error_implicit_ivar_access)
-            << IV->getDeclName();
-            Diag(ND->getLocation(), diag::note_declared_at);
-            return ExprError();
-          }
-        }
-      }
       return Owned(new (Context)
                    ObjCIvarRefExpr(IV, IV->getType(), Loc,
                                    SelfExpr.take(), true, true));
index 7d075db0c44235aa227861a7289586dc920a0130..0e448e31207dd3f0c52cd206703e1d4331862c72 100644 (file)
@@ -209,6 +209,7 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
                                bool Redeclaration) {
   unsigned IDNS = 0;
   switch (NameKind) {
+  case Sema::LookupObjCImplicitSelfParam:
   case Sema::LookupOrdinaryName:
   case Sema::LookupRedeclarationWithLinkage:
     IDNS = Decl::IDNS_Ordinary;
@@ -1097,7 +1098,10 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
           if (LeftStartingScope && !((*I)->hasLinkage()))
             continue;
         }
-
+        else if (NameKind == LookupObjCImplicitSelfParam &&
+                 !isa<ImplicitParamDecl>(*I))
+          continue;
+        
         R.addDecl(*I);
 
         if ((*I)->getAttr<OverloadableAttr>()) {
@@ -1381,6 +1385,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
   // Look for this member in our base classes
   CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0;
   switch (R.getLookupKind()) {
+    case LookupObjCImplicitSelfParam:
     case LookupOrdinaryName:
     case LookupMemberName:
     case LookupRedeclarationWithLinkage:
index 5c70c7edded7218576c057206729cdb77c7dd43c..a9b416b349460293bbe80054df4db54e50c79b6d 100644 (file)
@@ -1701,6 +1701,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
   TagDecl *OwnedTagDecl = 0;
 
   switch (D.getName().getKind()) {
+  case UnqualifiedId::IK_ImplicitSelfParam:
   case UnqualifiedId::IK_OperatorFunctionId:
   case UnqualifiedId::IK_Identifier:
   case UnqualifiedId::IK_LiteralOperatorId:
index 4bd72021443892323b8be3617ac62b5feeebce32..21310953c2c5d398311abc7de6b52bc939c0c500 100644 (file)
@@ -7,11 +7,12 @@
 @implementation Blocky {
     int _a;
 }
-- (void)doAThing {
+- (int)doAThing {
     ^{
-        char self; // expected-note {{declared here}}
-        _a; // expected-error {{instance variable '_a' cannot be accessed because 'self' has been redeclared}}
+        char self;
+        return _a;
     }();
+    return _a;
 }
 
 @end
         (void)_anIvar;
     }
     {
-      C* self; // expected-note {{declared here}}
-      (void) _anIvar; // expected-error {{instance variable '_anIvar' cannot be accessed because 'self' has been redeclared}}
+      C* self; 
+      (void) _anIvar;
     }
 }
 - (void)doAThing {
     ^{
-        id self;       // expected-note {{declared here}}
-       (void)_anIvar; // expected-error {{instance variable '_anIvar' cannot be accessed because 'self' has been redeclared}}
+        id self;
+       (void)_anIvar;
     }();
 }
 @end