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.

llvm-svn: 39436
This commit is contained in:
Steve Naroff 2007-05-07 21:22:42 +00:00
parent 35d8515be7
commit 6396921550
5 changed files with 51 additions and 8 deletions

View File

@ -728,9 +728,13 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
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>());

View File

@ -728,9 +728,13 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
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>());

View File

@ -248,10 +248,10 @@ public:
/// 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) {

View File

@ -48,6 +48,8 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
: 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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
/// 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 @@ public:
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 @@ public:
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 @@ public:
/// 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 @@ public:
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 @@ public:
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 @@ public:
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;

View File

@ -461,6 +461,8 @@ DIAG(err_redefinition_of_enumerator, ERROR,
"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'")