summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
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
commitbf8e842b671036b87d6f159ed13172423b112fe4 (patch)
tree08ee63dbfc5bc8e60d198df96aeb9ba21cb11de5 /clang/lib/Sema
parent53b72b4fea85450139076bbd20a603a09873414f (diff)
downloadbcm5719-llvm-bf8e842b671036b87d6f159ed13172423b112fe4.tar.gz
bcm5719-llvm-bf8e842b671036b87d6f159ed13172423b112fe4.zip
Diagnose a variety of access of ivars when they conflict with
local or global variables in instance/class methods. llvm-svn: 65879
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index aca19cdca67..32ef0f7b351 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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(
OpenPOWER on IntegriCloud