[cfe-commits] r39437 - in /cfe/cfe/trunk: AST/Expr.cpp AST/Sema.h AST/SemaDecl.cpp AST/SemaStmt.cpp AST/Type.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaStmt.cpp include/clang/AST/Expr.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def

Steve Naroff snaroff at apple.com
Wed Jul 11 09:44:23 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:44:23 2007
New Revision: 39437

URL: http://llvm.org/viewvc/llvm-project?rev=39437&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Added Sema::isConstantArrayType() and Type::isConstantSizeType().
- Implemented type checking for "variably modified" types (i.e. VLA's).
Added checking for file scope variables, static variables, member variables,
and typedefs.
- Changed Expr::isIntegerConstantExpr() to non-virtual implementation.
Fixed bug with sizeof/alignof. Looking at the diff, I may need to
add a check to exclude alignof.
- Added Expr::isConstantExpr()...non-virtual, like above.
- Added typechecking for case statements (found a bug with actions/parsing...).
- Added several diagnostics.
- Fixed several comments.
Started implemented constant expression checking for arrays.

Modified:
    cfe/cfe/trunk/AST/Expr.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/AST/SemaStmt.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaStmt.cpp
    cfe/cfe/trunk/include/clang/AST/Expr.h
    cfe/cfe/trunk/include/clang/AST/Type.h
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:44:23 2007
@@ -155,6 +155,56 @@
   }
 }
 
+bool Expr::isConstantExpr() const {
+  switch (getStmtClass()) {
+  case IntegerLiteralClass:
+  case FloatingLiteralClass:
+  case CharacterLiteralClass:
+  case StringLiteralClass:
+    return true;
+  case DeclRefExprClass:
+    return isa<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl());
+  case UnaryOperatorClass:
+    return cast<UnaryOperator>(this)->getSubExpr()->isConstantExpr();
+  case BinaryOperatorClass:
+    return cast<BinaryOperator>(this)->getLHS()->isConstantExpr() &&
+           cast<BinaryOperator>(this)->getRHS()->isConstantExpr();
+  case ParenExprClass:
+    return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr();
+  case CastExprClass:
+    return cast<CastExpr>(this)->getSubExpr()->isConstantExpr();
+  case SizeOfAlignOfTypeExprClass:
+    return cast<SizeOfAlignOfTypeExpr>(this)->getArgumentType()
+                                            ->isConstantSizeType();
+  default: 
+    return false;
+  }
+}
+
+bool Expr::isIntegerConstantExpr() const {
+  switch (getStmtClass()) {
+  case IntegerLiteralClass:
+  case CharacterLiteralClass:
+    return true;
+  case DeclRefExprClass:
+    return isa<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl());
+  case UnaryOperatorClass:
+    return cast<UnaryOperator>(this)->getSubExpr()->isIntegerConstantExpr();
+  case BinaryOperatorClass:
+    return cast<BinaryOperator>(this)->getLHS()->isIntegerConstantExpr() &&
+           cast<BinaryOperator>(this)->getRHS()->isIntegerConstantExpr();
+  case ParenExprClass:
+    return cast<ParenExpr>(this)->getSubExpr()->isIntegerConstantExpr();
+  case CastExprClass:
+    return cast<CastExpr>(this)->getSubExpr()->isIntegerConstantExpr();
+  case SizeOfAlignOfTypeExprClass:
+    return cast<SizeOfAlignOfTypeExpr>(this)->getArgumentType()
+                                            ->isConstantSizeType();
+  default: 
+    return false;
+  }
+}
+
 bool Expr::isNullPointerConstant() const {
   const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(this);
   if (!constant || constant->getValue() != 0)

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:44:23 2007
@@ -33,6 +33,7 @@
   class DeclaratorChunk;
   class LexerToken;
   class IntegerLiteral;
+  class ArrayType;
   
 /// Sema - This implements semantic analysis and AST building for C.
 class Sema : public Action {
@@ -243,9 +244,9 @@
   QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
                                       AssignmentConversionResult &r); 
   
-  /// the following "Check" methods will either return a well formed AST node
-  /// or will return true if the expressions didn't type check properly.
-  
+  /// the following "Check" methods will return a valid/converted QualType
+  /// or a null QualType (indicating an error diagnostic was issued).
+    
   /// type checking binary operators (subroutines of ParseBinOp).
   inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
     Expr *lex, Expr *rex, SourceLocation OpLoc); 
@@ -274,15 +275,16 @@
     Expr *lex, Expr *rex, SourceLocation OpLoc);
   
   /// type checking unary operators (subroutines of ParseUnaryOp).
-  /// The unsigned arguments are really enums (UnaryOperator::Opcode)
   QualType CheckIncrementDecrementOperand( // C99 6.5.3.1 
     Expr *op, SourceLocation loc);
   QualType CheckAddressOfOperand( // C99 6.5.3.2
     Expr *op, SourceLocation loc);
   QualType CheckIndirectionOperand( // C99 6.5.3.2
     Expr *op, SourceLocation loc);
-  ExprResult CheckArithmeticOperand( // C99 6.5.3.3
-    Expr *op, SourceLocation OpLoc, unsigned OpCode);
+    
+  // C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
+  // a constant expression of type int with a value greater than zero.
+  bool isConstantArrayType(ArrayType *ary, SourceLocation loc); 
 };
 
 

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:44:23 2007
@@ -27,6 +27,24 @@
 using namespace llvm;
 using namespace clang;
 
+// C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
+// a constant expression of type int with a value greater than zero.
+bool Sema::isConstantArrayType(ArrayType *ary, SourceLocation loc) { 
+  if (Expr *size = ary->getSize()) {
+    if (!size->isConstantExpr()) {
+      Diag(loc, diag::err_typecheck_illegal_vla);
+      return false;
+    }
+    if (!size->getType()->isIntegerType()) {
+      Diag(loc, diag::err_array_size_non_int, size->getType());
+      return false;
+    }
+    // We have a constant expression with an integer type, now make sure 
+    // value greater than zero (C99 6.7.5.2p1).
+    // FIXME: evaluate constant expression.
+  }
+  return true;
+}
 
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
   return dyn_cast_or_null<TypedefDecl>(II.getFETokenInfo<Decl>());
@@ -247,6 +265,14 @@
       if (NewTD == 0) return 0;
     }
     New = NewTD;
+    if (S->getParent() == 0) {
+      // C99 6.7.7p2: If a typedef name specifies a variably modified type
+      // then it shall have block scope.
+      if (ArrayType *ary = dyn_cast<ArrayType>(NewTD->getUnderlyingType())) {
+        if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+          return 0;
+      }
+    }
   } else if (D.isFunctionDeclarator()) {
     QualType R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
@@ -305,6 +331,12 @@
         Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope, R);
         return 0;
       }
+      // C99 6.7.5.2p2: If an identifier is declared to be an object with 
+      // static storage duration, it shall not have a variable length array.
+      if (ArrayType *ary = dyn_cast<ArrayType>(R)) {
+        if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+          return 0;
+      }
       NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
     } else { 
       // Block scope. C99 6.7p7: If an identifier for an object is declared with
@@ -315,6 +347,14 @@
           return 0;
         }
       }
+      if (SC == VarDecl::Static) {
+        // C99 6.7.5.2p2: If an identifier is declared to be an object with 
+        // static storage duration, it shall not have a variable length array.
+        if (ArrayType *ary = dyn_cast<ArrayType>(R)) {
+          if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+            return 0;
+        }
+      }
       NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC);
     }    
     // Merge the decl with the existing one if appropriate.
@@ -595,7 +635,13 @@
   
   QualType T = GetTypeForDeclarator(D, S);
   if (T.isNull()) return 0;
-
+  
+  // C99 6.7.2.1p8: A member of a structure or union may have any type other
+  // than a variably modified type.
+  if (ArrayType *ary = dyn_cast<ArrayType>(T)) {
+    if (!isConstantArrayType(ary, Loc))
+      return 0;
+  }
   return new FieldDecl(Loc, II, T);
 }
 

Modified: cfe/cfe/trunk/AST/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaStmt.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/AST/SemaStmt.cpp Wed Jul 11 11:44:23 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/Stmt.h"
+#include "clang/AST/Expr.h"
 #include "clang/Parse/Scope.h"
 #include "clang/Basic/Diagnostic.h"
 using namespace llvm;
@@ -34,6 +35,12 @@
 Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
                     SourceLocation DotDotDotLoc, ExprTy *RHSVal,
                     SourceLocation ColonLoc, StmtTy *SubStmt) {
+  assert((LHSVal != 0) && "missing expression in case statement");
+    
+  // C99 6.8.4.2p3: The expression shall be an integer constant.
+  if (!((Expr *)LHSVal)->isIntegerConstantExpr())
+    return Diag(CaseLoc, diag::err_case_label_not_integer_constant_expr);
+
   return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
 }
 

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:23 2007
@@ -14,6 +14,7 @@
 #include "clang/Lex/IdentifierTable.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
 
 #include <iostream>
 
@@ -263,6 +264,18 @@
   return CanonicalType->getTypeClass() == Array;
 }
 
+// The only variable size types are auto arrays within a function. Structures 
+// cannot contain a VLA member. They can have a flexible array member, however
+// the structure is still constant size (C99 6.7.2.1p16).
+bool Type::isConstantSizeType() const {
+  if (const ArrayType *ary = dyn_cast<ArrayType>(CanonicalType)) {
+    if (Expr *size = ary->getSize()) {
+      if (!size->isConstantExpr())
+        return false; // Variable Length Array
+    }
+  }
+  return true;
+}
 
 /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
 /// - a type that can describe objects, but which lacks information needed to

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:44:23 2007
@@ -33,6 +33,7 @@
   class DeclaratorChunk;
   class LexerToken;
   class IntegerLiteral;
+  class ArrayType;
   
 /// Sema - This implements semantic analysis and AST building for C.
 class Sema : public Action {
@@ -243,9 +244,9 @@
   QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
                                       AssignmentConversionResult &r); 
   
-  /// the following "Check" methods will either return a well formed AST node
-  /// or will return true if the expressions didn't type check properly.
-  
+  /// the following "Check" methods will return a valid/converted QualType
+  /// or a null QualType (indicating an error diagnostic was issued).
+    
   /// type checking binary operators (subroutines of ParseBinOp).
   inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
     Expr *lex, Expr *rex, SourceLocation OpLoc); 
@@ -274,15 +275,16 @@
     Expr *lex, Expr *rex, SourceLocation OpLoc);
   
   /// type checking unary operators (subroutines of ParseUnaryOp).
-  /// The unsigned arguments are really enums (UnaryOperator::Opcode)
   QualType CheckIncrementDecrementOperand( // C99 6.5.3.1 
     Expr *op, SourceLocation loc);
   QualType CheckAddressOfOperand( // C99 6.5.3.2
     Expr *op, SourceLocation loc);
   QualType CheckIndirectionOperand( // C99 6.5.3.2
     Expr *op, SourceLocation loc);
-  ExprResult CheckArithmeticOperand( // C99 6.5.3.3
-    Expr *op, SourceLocation OpLoc, unsigned OpCode);
+    
+  // C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
+  // a constant expression of type int with a value greater than zero.
+  bool isConstantArrayType(ArrayType *ary, SourceLocation loc); 
 };
 
 

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:44:23 2007
@@ -27,6 +27,24 @@
 using namespace llvm;
 using namespace clang;
 
+// C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
+// a constant expression of type int with a value greater than zero.
+bool Sema::isConstantArrayType(ArrayType *ary, SourceLocation loc) { 
+  if (Expr *size = ary->getSize()) {
+    if (!size->isConstantExpr()) {
+      Diag(loc, diag::err_typecheck_illegal_vla);
+      return false;
+    }
+    if (!size->getType()->isIntegerType()) {
+      Diag(loc, diag::err_array_size_non_int, size->getType());
+      return false;
+    }
+    // We have a constant expression with an integer type, now make sure 
+    // value greater than zero (C99 6.7.5.2p1).
+    // FIXME: evaluate constant expression.
+  }
+  return true;
+}
 
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
   return dyn_cast_or_null<TypedefDecl>(II.getFETokenInfo<Decl>());
@@ -247,6 +265,14 @@
       if (NewTD == 0) return 0;
     }
     New = NewTD;
+    if (S->getParent() == 0) {
+      // C99 6.7.7p2: If a typedef name specifies a variably modified type
+      // then it shall have block scope.
+      if (ArrayType *ary = dyn_cast<ArrayType>(NewTD->getUnderlyingType())) {
+        if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+          return 0;
+      }
+    }
   } else if (D.isFunctionDeclarator()) {
     QualType R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
@@ -305,6 +331,12 @@
         Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope, R);
         return 0;
       }
+      // C99 6.7.5.2p2: If an identifier is declared to be an object with 
+      // static storage duration, it shall not have a variable length array.
+      if (ArrayType *ary = dyn_cast<ArrayType>(R)) {
+        if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+          return 0;
+      }
       NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
     } else { 
       // Block scope. C99 6.7p7: If an identifier for an object is declared with
@@ -315,6 +347,14 @@
           return 0;
         }
       }
+      if (SC == VarDecl::Static) {
+        // C99 6.7.5.2p2: If an identifier is declared to be an object with 
+        // static storage duration, it shall not have a variable length array.
+        if (ArrayType *ary = dyn_cast<ArrayType>(R)) {
+          if (!isConstantArrayType(ary, D.getIdentifierLoc()))
+            return 0;
+        }
+      }
       NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC);
     }    
     // Merge the decl with the existing one if appropriate.
@@ -595,7 +635,13 @@
   
   QualType T = GetTypeForDeclarator(D, S);
   if (T.isNull()) return 0;
-
+  
+  // C99 6.7.2.1p8: A member of a structure or union may have any type other
+  // than a variably modified type.
+  if (ArrayType *ary = dyn_cast<ArrayType>(T)) {
+    if (!isConstantArrayType(ary, Loc))
+      return 0;
+  }
   return new FieldDecl(Loc, II, T);
 }
 

Modified: cfe/cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaStmt.cpp?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaStmt.cpp Wed Jul 11 11:44:23 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/Stmt.h"
+#include "clang/AST/Expr.h"
 #include "clang/Parse/Scope.h"
 #include "clang/Basic/Diagnostic.h"
 using namespace llvm;
@@ -34,6 +35,12 @@
 Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
                     SourceLocation DotDotDotLoc, ExprTy *RHSVal,
                     SourceLocation ColonLoc, StmtTy *SubStmt) {
+  assert((LHSVal != 0) && "missing expression in case statement");
+    
+  // C99 6.8.4.2p3: The expression shall be an integer constant.
+  if (!((Expr *)LHSVal)->isIntegerConstantExpr())
+    return Diag(CaseLoc, diag::err_case_label_not_integer_constant_expr);
+
   return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
 }
 

Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:44:23 2007
@@ -48,7 +48,8 @@
   
   bool isNullPointerConstant() const;
 
-  virtual bool isIntegerConstantExpr() const { return false; }
+  bool isConstantExpr() const;
+  bool isIntegerConstantExpr() const;
   
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
@@ -71,9 +72,6 @@
   
   Decl *getDecl() const { return D; }
 
-  virtual bool isIntegerConstantExpr() const { 
-    return isa<EnumConstantDecl>(D); }
-    
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DeclRefExprClass; 
@@ -92,8 +90,6 @@
   }
   intmax_t getValue() const { return Value; }
 
-  virtual bool isIntegerConstantExpr() const { return true; }
-  
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IntegerLiteralClass; 
@@ -108,9 +104,6 @@
   CharacterLiteral(unsigned value, QualType type)
     : Expr(CharacterLiteralClass, type), Value(value) {
   }
-
-  virtual bool isIntegerConstantExpr() const { return true; }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CharacterLiteralClass; 
@@ -124,8 +117,6 @@
   FloatingLiteral(float value, QualType type) : 
     Expr(FloatingLiteralClass, type), Value(value) {} 
 
-  virtual bool isIntegerConstantExpr() const { return false; }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == FloatingLiteralClass; 
@@ -145,8 +136,6 @@
   unsigned getByteLength() const { return ByteLength; }
   bool isWide() const { return IsWide; }
 
-  virtual bool isIntegerConstantExpr() const { return false; }
-  
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == StringLiteralClass; 
@@ -165,9 +154,6 @@
   
   Expr *getSubExpr() const { return Val; }
 
-  virtual bool isIntegerConstantExpr() const { 
-    return Val->isIntegerConstantExpr(); }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ParenExprClass; 
@@ -215,9 +201,6 @@
   /// the following complex expression "s.zz[2].bb.vv".
   static bool isAddressable(Expr *e);
 
-  virtual bool isIntegerConstantExpr() const { 
-    return Val->isIntegerConstantExpr(); }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == UnaryOperatorClass; 
@@ -242,8 +225,6 @@
   bool isSizeOf() const { return isSizeof; }
   QualType getArgumentType() const { return Ty; }
 
-  virtual bool isIntegerConstantExpr() const { return true; }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == SizeOfAlignOfTypeExprClass; 
@@ -266,8 +247,6 @@
   Expr *getBase() const { return Base; }
   Expr *getIdx() { return Idx; }
 
-  virtual bool isIntegerConstantExpr() const { return false; }
-  
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ArraySubscriptExprClass; 
@@ -304,8 +283,6 @@
   /// this function call.
   unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
 
-  virtual bool isIntegerConstantExpr() const { return false; }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CallExprClass; 
@@ -328,8 +305,6 @@
   FieldDecl *getMemberDecl() const { return MemberDecl; }
   bool isArrow() const { return IsArrow; }
 
-  virtual bool isIntegerConstantExpr() const { return false; }
-  
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == MemberExprClass; 
@@ -350,11 +325,8 @@
   
   QualType getDestType() const { return Ty; }
   
-  Expr *getSubExpr() { return Op; }
+  Expr *getSubExpr() const { return Op; }
   
-  virtual bool isIntegerConstantExpr() const { 
-    return Op->isIntegerConstantExpr(); }
-
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CastExprClass; 
@@ -404,12 +376,9 @@
   static bool isAssignmentOp(Opcode Op) { return Op >= Assign && Op<=OrAssign; }
   
   Opcode getOpcode() const { return Opc; }
-  Expr *getLHS() { return LHS; }
-  Expr *getRHS() { return RHS; }
+  Expr *getLHS() const { return LHS; }
+  Expr *getRHS() const { return RHS; }
 
-  virtual bool isIntegerConstantExpr() const { 
-    return LHS->isIntegerConstantExpr() && RHS->isIntegerConstantExpr(); }
-    
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == BinaryOperatorClass; 

Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:23 2007
@@ -234,6 +234,8 @@
   bool isSignedIntegerType() const;     // C99 6.2.5p4
   bool isUnsignedIntegerType() const;   // C99 6.2.5p6
   
+  bool isConstantSizeType() const; // C99 6.7.5p3: VLA if false
+
   /// Compatibility predicates used to check assignment expressions.
   static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
   static bool structureTypesAreCompatible(QualType, QualType); // C99 6.2.7p1

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39437&r1=39436&r2=39437&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:23 2007
@@ -462,7 +462,13 @@
 DIAG(err_duplicate_member, ERROR,
      "duplicate member '%s'")
 DIAG(err_enum_value_not_integer_constant_expr, ERROR,
-     "enumerator value for '%s' is not an integer constant expression")
+     "enumerator value for '%s' is not an integer constant")
+DIAG(err_case_label_not_integer_constant_expr, ERROR,
+     "case label does not reduce to an integer constant")
+DIAG(err_typecheck_illegal_vla, ERROR,
+     "variable length array declared outside of any function")
+DIAG(err_array_size_non_int, ERROR,
+     "size of array has non-integer type '%s'")
 
 DIAG(warn_implicit_function_decl, WARNING,
      "implicit declaration of function '%s'")





More information about the cfe-commits mailing list