[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