aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-07-12 17:16:56 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-07-12 17:16:56 +0000
commit98a5403ecf1d2b60ae8cbf43e54194bd762cacaa (patch)
treecc778b48931695ba912e3bd39e0de3a5edf19f9c
parent5bcd95efc380b0f7e74290e0555facb760935767 (diff)
Fix a bug where a local variable named 'self' is causing
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
-rw-r--r--include/clang/Sema/DeclSpec.h7
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaDecl.cpp1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--lib/Sema/SemaExpr.cpp26
-rw-r--r--lib/Sema/SemaLookup.cpp7
-rw-r--r--lib/Sema/SemaType.cpp1
-rw-r--r--test/SemaObjC/self-declared-in-block.m15
8 files changed, 28 insertions, 32 deletions
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index e3bc5bff57..cbf47e8b05 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -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.
///
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 54debed697..263c1bd49a 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -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
};
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 49c3f8a48f..c5caae279c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e20ec40b6a..62c163435c 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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:
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9f91052e4c..fa8721ce34 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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));
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 7d075db0c4..0e448e3120 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -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:
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 5c70c7edde..a9b416b349 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -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:
diff --git a/test/SemaObjC/self-declared-in-block.m b/test/SemaObjC/self-declared-in-block.m
index 4bd7202144..21310953c2 100644
--- a/test/SemaObjC/self-declared-in-block.m
+++ b/test/SemaObjC/self-declared-in-block.m
@@ -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
@@ -37,14 +38,14 @@
(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