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

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


Author: snaroff
Date: Wed Jul 11 11:44:22 2007
New Revision: 39436

URL: http://llvm.org/viewvc/llvm-project?rev=39436&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Start work on typechecking constant expressions.

- Added isIntegerConstantExpr() predicate to all exprs.
- Use the predicate to implement checking for enum constant initializers.
- Added diagnostic.
- Added Init slot to EnumConstantDecl class/constructor.

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

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:44:22 2007
@@ -728,9 +728,13 @@
       return 0;
     }
   }
-  
+  // C99 6.7.2.2p2: Make sure we have an integer constant expression.
+  if (Val && !((Expr *)Val)->isIntegerConstantExpr()) {
+    Diag(IdLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
+    return 0;
+  }
   QualType Ty = Context.getTagDeclType(TheEnumDecl);
-  EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty);
+  EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val);
   
   // Register this decl in the current scope stack.
   New->setNext(Id->getFETokenInfo<Decl>());

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:44:22 2007
@@ -728,9 +728,13 @@
       return 0;
     }
   }
-  
+  // C99 6.7.2.2p2: Make sure we have an integer constant expression.
+  if (Val && !((Expr *)Val)->isIntegerConstantExpr()) {
+    Diag(IdLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
+    return 0;
+  }
   QualType Ty = Context.getTagDeclType(TheEnumDecl);
-  EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty);
+  EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val);
   
   // Register this decl in the current scope stack.
   New->setNext(Id->getFETokenInfo<Decl>());

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:44:22 2007
@@ -248,10 +248,10 @@
 /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
 /// TagType for the X EnumDecl.
 class EnumConstantDecl : public ValueDecl {
+  Expr *Init; // an integer constant expression
 public:
-  // FIXME: Capture value info.
-  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
-    : ValueDecl(EnumConstant, L, Id, T) {}
+  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E)
+    : ValueDecl(EnumConstant, L, Id, T), Init(E) {}
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {

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=39436&r1=39435&r2=39436&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:44:22 2007
@@ -48,6 +48,8 @@
   
   bool isNullPointerConstant() const;
 
+  virtual bool isIntegerConstantExpr() const { return false; }
+  
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() >= firstExprConstant &&
@@ -68,6 +70,9 @@
   DeclRefExpr(Decl *d, QualType t) : Expr(DeclRefExprClass, t), D(d) {}
   
   Decl *getDecl() const { return D; }
+
+  virtual bool isIntegerConstantExpr() const { 
+    return isa<EnumConstantDecl>(D); }
     
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
@@ -86,6 +91,8 @@
     assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
   }
   intmax_t getValue() const { return Value; }
+
+  virtual bool isIntegerConstantExpr() const { return true; }
   
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
@@ -102,6 +109,8 @@
     : 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; 
@@ -115,6 +124,8 @@
   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; 
@@ -133,6 +144,8 @@
   const char *getStrData() const { return StrData; }
   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) { 
@@ -152,6 +165,9 @@
   
   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; 
@@ -199,6 +215,9 @@
   /// 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; 
@@ -223,6 +242,8 @@
   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; 
@@ -244,6 +265,8 @@
   
   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) { 
@@ -281,6 +304,8 @@
   /// 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; 
@@ -302,6 +327,8 @@
   Expr *getBase() const { return Base; }
   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) { 
@@ -325,6 +352,9 @@
   
   Expr *getSubExpr() { return Op; }
   
+  virtual bool isIntegerConstantExpr() const { 
+    return Op->isIntegerConstantExpr(); }
+
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CastExprClass; 
@@ -376,7 +406,10 @@
   Opcode getOpcode() const { return Opc; }
   Expr *getLHS() { return LHS; }
   Expr *getRHS() { 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/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39436&r1=39435&r2=39436&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:22 2007
@@ -461,6 +461,8 @@
      "redefinition of enumerator '%s'")
 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")
 
 DIAG(warn_implicit_function_decl, WARNING,
      "implicit declaration of function '%s'")





More information about the cfe-commits mailing list