diff options
-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; } |