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
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index f27419c..a621119 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -745,6 +745,33 @@
   }
 }
 
+/// 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))