[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