aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-03-02 21:55:29 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-03-02 21:55:29 +0000
commit077c1e7377edeef3438ba59cd8151177868b62d4 (patch)
tree4985351aff694e6708fdc5d2b1344ab7365c30bf /lib
parentae3487f78747512ce718c6c00ef888787da50a1e (diff)
Diagnose a variety of access of ivars when they conflict with
local or global variables in instance/class methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65879 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaExpr.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index aca19cdca6..32ef0f7b35 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -627,27 +627,42 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (II && getCurMethodDecl()) {
// There are two cases to handle here. 1) scoped lookup could have failed,
// in which case we should look for an ivar. 2) scoped lookup could have
- // found a decl, but that decl is outside the current method (i.e. a global
- // variable). In these two cases, we do a lookup for an ivar with this
- // name, if the lookup suceeds, we replace it our current decl.
+ // found a decl, but that decl is outside the current instance method (i.e.
+ // a global variable). In these two cases, we do a lookup for an ivar with
+ // this name, if the lookup sucedes, we replace it our current decl.
if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) {
// Check if referencing a field with __attribute__((deprecated)).
if (DiagnoseUseOfDecl(IV, Loc))
return ExprError();
-
- // FIXME: This should use a new expr for a direct reference, don't turn
- // this into Self->ivar, just return a BareIVarExpr or something.
- IdentifierInfo &II = Context.Idents.get("self");
- OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
- ObjCIvarRefExpr *MRef = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
- Loc, static_cast<Expr*>(SelfExpr.release()),
- true, true);
- Context.setFieldDecl(IFace, IV, MRef);
- return Owned(MRef);
+ bool IsClsMethod = getCurMethodDecl()->isClassMethod();
+ // If a class method attemps to use a free standing ivar, this is
+ // an error.
+ if (IsClsMethod && D && !D->isDefinedOutsideFunctionOrMethod())
+ return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
+ << IV->getDeclName());
+ // If a class method uses a global variable, even if an ivar with
+ // same name exists, use the global.
+ if (!IsClsMethod) {
+ // FIXME: This should use a new expr for a direct reference, don't turn
+ // this into Self->ivar, just return a BareIVarExpr or something.
+ IdentifierInfo &II = Context.Idents.get("self");
+ OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
+ ObjCIvarRefExpr *MRef = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
+ Loc, static_cast<Expr*>(SelfExpr.release()),
+ true, true);
+ Context.setFieldDecl(IFace, IV, MRef);
+ return Owned(MRef);
+ }
}
}
+ else if (getCurMethodDecl()->isInstanceMethod()) {
+ // We should warn if a local variable hides an ivar.
+ ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II))
+ Diag(Loc, diag::warn_ivar_use_hidden)<<IV->getDeclName();
+ }
// Needed to implement property "super.method" notation.
if (D == 0 && II->isStr("super")) {
QualType T = Context.getPointerType(Context.getObjCInterfaceType(