diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-22 18:40:18 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-22 18:40:18 +0000 |
commit | 44baa8abba2a1552b6b50bf750a8750ab9da9f76 (patch) | |
tree | 87c697364252ff26d0f35fa50deb91ddff9c2556 | |
parent | 6eef49819da450de398dcbe008066ccc9546ee31 (diff) |
More objc gc work. Match gcc's treatment of ivar access
true a local pointer to objective-c object in generating
write barriers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65290 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 4 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 27 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 2 |
3 files changed, 32 insertions, 1 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 3745866f75..cfd13b2fbb 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -238,6 +238,10 @@ public: /// duration. This means that the address of this expression is a link-time /// constant. bool hasGlobalStorage() const; + + /// isOBJCGCCandidate - Return true if this expression may be used in a read/ + /// write barrier. + bool isOBJCGCCandidate() const; /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return /// its subexpression. If that subexpression is also a ParenExpr, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index f27419c0a2..a621119dae 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -745,6 +745,33 @@ bool Expr::hasGlobalStorage() const { } } +/// isOBJCGCCandidate - Check if an expression is objc gc'able. +/// +bool Expr::isOBJCGCCandidate() const { + switch (getStmtClass()) { + default: + return false; + case ObjCIvarRefExprClass: + return true; + case ParenExprClass: + return cast<ParenExpr>(this)->getSubExpr()->isOBJCGCCandidate(); + case ImplicitCastExprClass: + return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(); + case DeclRefExprClass: + case QualifiedDeclRefExprClass: { + const Decl *D = cast<DeclRefExpr>(this)->getDecl(); + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + return VD->hasGlobalStorage(); + return false; + } + case MemberExprClass: { + const MemberExpr *M = cast<MemberExpr>(this); + return !M->isArrow() && M->getBase()->isOBJCGCCandidate(); + } + case ArraySubscriptExprClass: + return cast<ArraySubscriptExpr>(this)->getBase()->isOBJCGCCandidate(); + } +} Expr* Expr::IgnoreParens() { Expr* E = this; while (ParenExpr* P = dyn_cast<ParenExpr>(E)) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 2348a11f7b..c96265242a 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -782,7 +782,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { getContext().getObjCGCAttrKind(T)); if (getContext().getLangOptions().ObjC1 && getContext().getLangOptions().getGCMode() != LangOptions::NonGC) - LValue::SetObjCNonGC(LV, !E->hasGlobalStorage()); + LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate()); return LV; } |