improve handling of address of global when checking for
constants and initializers.  Patch by Sanghyeon Seo, thanks!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44049 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Expr.cpp b/AST/Expr.cpp
index 4505fec..10f0895 100644
--- a/AST/Expr.cpp
+++ b/AST/Expr.cpp
@@ -359,6 +359,22 @@
   return MLV_Valid;    
 }
 
+bool Expr::hasStaticStorage() const {
+  switch (getStmtClass()) {
+  default:
+    return false;
+  case DeclRefExprClass: {
+    const Decl *D = cast<DeclRefExpr>(this)->getDecl();
+    if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+      return VD->hasStaticStorage();
+    return false;
+  }
+  case MemberExprClass:
+    const MemberExpr *M = cast<MemberExpr>(this);
+    return !M->isArrow() && M->getBase()->hasStaticStorage();
+  }
+}
+
 bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
   switch (getStmtClass()) {
   default:
@@ -391,11 +407,17 @@
     if (isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D))
       return true;
     if (Loc) *Loc = getLocStart();
+    if (isa<VarDecl>(D))
+      return TR->isArrayType();
     return false;
   }
   case UnaryOperatorClass: {
     const UnaryOperator *Exp = cast<UnaryOperator>(this);
     
+    // C99 6.6p9
+    if (Exp->getOpcode() == UnaryOperator::AddrOf)
+      return Exp->getSubExpr()->hasStaticStorage();
+
     // Get the operand value.  If this is sizeof/alignof, do not evalute the
     // operand.  This affects C99 6.6p3.
     if (!Exp->isSizeOfAlignOfOp() &&