2007/11/12, Sanghyeon Seo <[EMAIL PROTECTED]>:
> A rather incomplete implementation and a test is attached.

A little better implementation and a little better test is attached. I
paste the test inline for comments.

// RUN: clang -fsyntax-only -verify %s

int i;
int a[] = {0};
struct { int i; } s;

int *array[] = {&i, a, &s.i};

-- 
Seo Sanghyeon
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang.orig/include/clang/AST/Expr.h 2007-11-12 09:22:11.000000000 +0900
+++ clang/include/clang/AST/Expr.h      2007-11-12 09:22:17.000000000 +0900
@@ -105,6 +105,10 @@
   /// isConstantExpr - Return true if this expression is a valid constant expr.
   bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const;
   
+  /// hasStaticStorage - Return true if this expression has static storage
+  /// duration.
+  bool hasStaticStorage() const;
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() >= firstExprConstant &&
            T->getStmtClass() <= lastExprConstant; 
Index: clang/AST/Expr.cpp
===================================================================
--- clang.orig/AST/Expr.cpp     2007-11-12 09:24:59.000000000 +0900
+++ clang/AST/Expr.cpp  2007-11-12 09:25:03.000000000 +0900
@@ -357,6 +357,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:
@@ -389,11 +405,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() &&
Index: clang/test/Sema/address-constant.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ clang/test/Sema/address-constant.c  2007-11-12 09:10:57.000000000 +0900
@@ -0,0 +1,7 @@
+// RUN: clang -fsyntax-only -verify %s
+
+int i;
+int a[] = {0};
+struct { int i; } s;
+
+int *array[] = {&i, a, &s.i};
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

Reply via email to