summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-04-02 18:57:54 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-04-02 18:57:54 +0000
commitf12ff4df48e74ac553bf138633afdc95444e4c0b (patch)
tree1b4df9f302556b2aa79235b88eaf9d6ace95e8f9 /clang/lib
parent55a634996f4769b1bc6c1062d895043edeafc298 (diff)
downloadbcm5719-llvm-f12ff4df48e74ac553bf138633afdc95444e4c0b.tar.gz
bcm5719-llvm-f12ff4df48e74ac553bf138633afdc95444e4c0b.zip
Objective-C: Provide fixit hints when warning
about 'isa' ivar being explicitely accessed when base is a user class object reference. // rdar://13503456 llvm-svn: 178562
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp40
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp2
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp2
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp1
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp1
6 files changed, 41 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 9ee3c8b60e0..e8378becf12 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1189,7 +1189,8 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
selfDecl->getType(), CK_LValueToRValue, &self,
VK_RValue);
ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
- SourceLocation(), &selfLoad, true, true);
+ SourceLocation(), SourceLocation(),
+ &selfLoad, true, true);
ParmVarDecl *argDecl = *setterMethod->param_begin();
QualType argType = argDecl->getType().getNonReferenceType();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c1d86550a53..5459d74016f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -456,7 +456,8 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) {
}
static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
- bool IsAssign) {
+ SourceLocation AssignLoc,
+ const Expr* RHS) {
const ObjCIvarDecl *IV = OIRE->getDecl();
if (!IV)
return;
@@ -476,8 +477,35 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
if (!ClassDeclared->getSuperClass()
&& (*ClassDeclared->ivar_begin()) == IV) {
- S.Diag(OIRE->getLocation(), IsAssign ? diag::warn_objc_isa_assign
- : diag::warn_objc_isa_use);
+ if (RHS) {
+ NamedDecl *ObjectSetClass =
+ S.LookupSingleName(S.TUScope,
+ &S.Context.Idents.get("object_setClass"),
+ SourceLocation(), S.LookupOrdinaryName);
+ if (ObjectSetClass) {
+ SourceLocation RHSLocEnd = S.PP.getLocForEndOfToken(RHS->getLocEnd());
+ S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) <<
+ FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") <<
+ FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(),
+ AssignLoc), ",") <<
+ FixItHint::CreateInsertion(RHSLocEnd, ")");
+ }
+ else
+ S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign);
+ } else {
+ NamedDecl *ObjectGetClass =
+ S.LookupSingleName(S.TUScope,
+ &S.Context.Idents.get("object_getClass"),
+ SourceLocation(), S.LookupOrdinaryName);
+ if (ObjectGetClass)
+ S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) <<
+ FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") <<
+ FixItHint::CreateReplacement(
+ SourceRange(OIRE->getOpLoc(),
+ OIRE->getLocEnd()), ")");
+ else
+ S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use);
+ }
S.Diag(IV->getLocation(), diag::note_ivar_decl);
}
}
@@ -538,7 +566,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
}
else if (const ObjCIvarRefExpr *OIRE =
dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
- DiagnoseDirectIsaAccess(*this, OIRE, false);
+ DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/0);
// C++ [conv.lval]p1:
// [...] If T is a non-class type, the type of the prvalue is the
@@ -2104,7 +2132,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();
ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
- Loc,
+ Loc, IV->getLocation(),
SelfExpr.take(),
true, true);
@@ -8628,7 +8656,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
}
else if (const ObjCIvarRefExpr *OIRE =
dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts()))
- DiagnoseDirectIsaAccess(*this, OIRE, true);
+ DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
if (CompResultTy.isNull())
return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc,
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 54190edf37d..847db24632b 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1252,7 +1252,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
}
ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
- MemberLoc,
+ MemberLoc, OpLoc,
BaseExpr.take(),
IsArrow);
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index c507ab7007b..7ad8bc722d5 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -1136,6 +1136,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
MarkDeclRefReferenced(SelfExpr);
Expr *IvarRefExpr =
new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
+ Ivar->getLocation(),
SelfExpr, true, true);
ExprResult Res =
PerformCopyInitialization(InitializedEntity::InitializeResult(
@@ -1171,6 +1172,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
MarkDeclRefReferenced(SelfExpr);
Expr *lhs =
new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
+ Ivar->getLocation(),
SelfExpr, true, true);
ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
ParmVarDecl *Param = (*P);
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 6159916c825..078ecb7a06d 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -893,6 +893,7 @@ void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
VisitExpr(E);
E->setDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
+ E->setOpLoc(ReadSourceLocation(Record, Idx));
E->setBase(Reader.ReadSubExpr());
E->setIsArrow(Record[Idx++]);
E->setIsFreeIvar(Record[Idx++]);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index bb8afb8652b..b6f1d54d407 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -857,6 +857,7 @@ void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
VisitExpr(E);
Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
+ Writer.AddSourceLocation(E->getOpLoc(), Record);
Writer.AddStmt(E->getBase());
Record.push_back(E->isArrow());
Record.push_back(E->isFreeIvar());
OpenPOWER on IntegriCloud