]> granicus.if.org Git - clang/commitdiff
More objc gc work. Match gcc's treatment of ivar access
authorFariborz Jahanian <fjahanian@apple.com>
Sun, 22 Feb 2009 18:40:18 +0000 (18:40 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sun, 22 Feb 2009 18:40:18 +0000 (18:40 +0000)
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

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/CodeGen/CGExpr.cpp

index 3745866f75c0d975fa041555bb95c7a9e1017bec..cfd13b2fbbf92f1ade5da876ffdbc9c3f1ab18ec 100644 (file)
@@ -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, 
index f27419c0a240c314ff013b8091c7a760f7133e8a..a621119daefb1a7f4f8a0adbe996bfc56dd45a95 100644 (file)
@@ -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))
index 2348a11f7b0d8f1ab9c8a43d145d8327b35fd46d..c96265242ac4dad414b256782d78a1920a894932 100644 (file)
@@ -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;
 }