[cfe-commits] r39446 - in /cfe/cfe/trunk: AST/Expr.cpp AST/Sema.h AST/SemaExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Expr.h
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:30 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:30 2007
New Revision: 39446
URL: http://llvm.org/viewvc/llvm-project?rev=39446&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Unified isConstantExpr/isIntegerConstantExpr by creating a private function
named isConstantExpr (that takes a bool to indicate the flavor). isConstantExpr
and isIntegerConstantExpr are now inline wrapper/helper functions.
- Fixed bug in expression based sizeof (it needed to make sure the type is constant).
- Added Sema::CheckConditionalOperands() stub. Will add contraints in my next commit.
Modified:
cfe/cfe/trunk/AST/Expr.cpp
cfe/cfe/trunk/AST/Sema.h
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Expr.h
Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:44:30 2007
@@ -175,13 +175,26 @@
return true;
}
-bool Expr::isConstantExpr() const {
+/// isConstantExpr - this recursive routine will test if an expression is
+/// either a constant expression (isIntConst == false) or an integer constant
+/// expression (isIntConst == true). Note: With the introduction of VLA's in
+/// C99 the result of the sizeof operator is no longer always a constant
+/// expression. The generalization of the wording to include any subexpression
+/// that is not evaluated (C99 6.6p3) means that nonconstant subexpressions
+/// can appear as operands to other operators (e.g. &&, ||, ?:). For instance,
+/// "0 || f()" can be treated as a constant expression. In C90 this expression,
+/// occurring in a context requiring a constant, would have been a constraint
+/// violation. FIXME: This routine currently implements C90 semantics.
+/// To properly implement C99 semantics this routine will need to evaluate
+/// expressions involving operators previously mentioned.
+bool Expr::isConstantExpr(bool isIntConst) const {
switch (getStmtClass()) {
case IntegerLiteralClass:
- case FloatingLiteralClass:
case CharacterLiteralClass:
- case StringLiteralClass:
return true;
+ case FloatingLiteralClass:
+ case StringLiteralClass:
+ return isIntConst ? false : true;
case DeclRefExprClass:
return isa<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl());
case UnaryOperatorClass:
@@ -192,8 +205,8 @@
// is an integer constant. This effective ignores any subexpression that
// isn't actually a constant expression (what an odd language:-)
if (uop->isSizeOfAlignOfOp())
- return true;
- return uop->getSubExpr()->isConstantExpr();
+ return uop->getSubExpr()->getType()->isConstantSizeType();
+ return uop->getSubExpr()->isConstantExpr(isIntConst);
case BinaryOperatorClass:
const BinaryOperator *bop = cast<BinaryOperator>(this);
// C99 6.6p3: shall not contain assignment, increment/decrement,
@@ -201,7 +214,8 @@
// within a subexpression that is not evaluated.
if (bop->isAssignmentOp() || bop->getOpcode() == BinaryOperator::Comma)
return false;
- return bop->getLHS()->isConstantExpr() && bop->getRHS()->isConstantExpr();
+ return bop->getLHS()->isConstantExpr(isIntConst) &&
+ bop->getRHS()->isConstantExpr(isIntConst);
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr();
case CastExprClass:
@@ -222,73 +236,10 @@
return sizeExpr->getArgumentType()->isConstantSizeType();
return true; // alignof will always evaluate to a constant
case ConditionalOperatorClass:
- // GCC currently ignores any subexpression that isn't evaluated.
- // GCC currently considers the following legal: "1 ? 7 : printf("xx")"
- // EDG still flags this as an error (which is great, since this predicate
- // can do it's job *without* evaluating the expression).
- const ConditionalOperator *condExpr = cast<ConditionalOperator>(this);
- return condExpr->getCond()->isConstantExpr() &&
- condExpr->getLHS()->isConstantExpr() &&
- condExpr->getRHS()->isConstantExpr();
- 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:
- const UnaryOperator *uop = cast<UnaryOperator>(this);
- if (uop->isIncrementDecrementOp()) // C99 6.6p3
- return false;
- // C99 6.5.3.4p2: otherwise, the operand is *not* evaluated and the result
- // is an integer constant. This effective ignores any subexpression that
- // isn't actually a constant expression (what an odd language:-)
- if (uop->isSizeOfAlignOfOp())
- return true;
- return uop->getSubExpr()->isIntegerConstantExpr();
- case BinaryOperatorClass:
- const BinaryOperator *bop = cast<BinaryOperator>(this);
- // C99 6.6p3: shall not contain assignment, increment/decrement,
- // function call, or comma operators, *except* when they are contained
- // within a subexpression that is not evaluated.
- if (bop->isAssignmentOp() || bop->getOpcode() == BinaryOperator::Comma)
- return false;
- return bop->getLHS()->isIntegerConstantExpr() &&
- bop->getRHS()->isIntegerConstantExpr();
- case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->isIntegerConstantExpr();
- case CastExprClass:
- const CastExpr *castExpr = cast<CastExpr>(this);
- // C99 6.6p6: shall only convert arithmetic types to integer types.
- if (!castExpr->getSubExpr()->getType()->isArithmeticType())
- return false;
- if (!castExpr->getDestType()->isIntegerType())
- return false;
- // allow floating constants that are the immediate operands of casts.
- if (castExpr->getSubExpr()->isIntegerConstantExpr() ||
- isa<FloatingLiteral>(castExpr->getSubExpr()))
- return true;
- return false;
- case SizeOfAlignOfTypeExprClass:
- const SizeOfAlignOfTypeExpr *sizeExpr = cast<SizeOfAlignOfTypeExpr>(this);
- if (sizeExpr->isSizeOf())
- return sizeExpr->getArgumentType()->isConstantSizeType();
- return true; // alignof will always evaluate to a constant
- case ConditionalOperatorClass:
- // GCC currently ignores any subexpression that isn't evaluated.
- // GCC currently considers the following legal: "1 ? 7 : printf("xx")"
- // EDG still flags this as an error (which is great, since this predicate
- // can do it's job *without* evaluating the expression).
const ConditionalOperator *condExpr = cast<ConditionalOperator>(this);
- return condExpr->getCond()->isIntegerConstantExpr() &&
- condExpr->getLHS()->isIntegerConstantExpr() &&
- condExpr->getRHS()->isIntegerConstantExpr();
+ return condExpr->getCond()->isConstantExpr(isIntConst) &&
+ condExpr->getLHS()->isConstantExpr(isIntConst) &&
+ condExpr->getRHS()->isConstantExpr(isIntConst);
default:
return false;
}
Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:44:30 2007
@@ -274,6 +274,8 @@
Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType);
inline QualType CheckCommaOperands( // C99 6.5.17
Expr *lex, Expr *rex, SourceLocation OpLoc);
+ inline QualType CheckConditionalOperands( // C99 6.5.15
+ Expr *cond, Expr *lhs, Expr *rhs, SourceLocation questionLoc);
/// type checking unary operators (subroutines of ParseUnaryOp).
QualType CheckIncrementDecrementOperand( // C99 6.5.3.1
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:30 2007
@@ -384,20 +384,31 @@
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op);
}
+inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
+ Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation questionLoc) {
+ QualType cond = Cond->getType().getCanonicalType();
+ QualType lhs = LHS->getType().getCanonicalType();
+ QualType rhs = RHS->getType().getCanonicalType();
+
+ assert(!cond.isNull() && "ParseConditionalOp(): no conditional type");
+ assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
+ assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
+
+ // C99 6.5.15p2,3
+ return rhs;
+}
+
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS,
ExprTy *RHS) {
- QualType lhs = ((Expr *)LHS)->getType();
- QualType rhs = ((Expr *)RHS)->getType();
-
- assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
- assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
-
- QualType canonType = rhs.getCanonicalType(); // FIXME
- return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, canonType);
+ QualType result = CheckConditionalOperands((Expr *)Cond, (Expr *)LHS,
+ (Expr *)RHS, QuestionLoc);
+ if (result.isNull())
+ return true;
+ return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
}
/// UsualUnaryConversion - Performs various conversions that are common to most
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:44:30 2007
@@ -274,6 +274,8 @@
Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType);
inline QualType CheckCommaOperands( // C99 6.5.17
Expr *lex, Expr *rex, SourceLocation OpLoc);
+ inline QualType CheckConditionalOperands( // C99 6.5.15
+ Expr *cond, Expr *lhs, Expr *rhs, SourceLocation questionLoc);
/// type checking unary operators (subroutines of ParseUnaryOp).
QualType CheckIncrementDecrementOperand( // C99 6.5.3.1
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:30 2007
@@ -384,20 +384,31 @@
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op);
}
+inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
+ Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation questionLoc) {
+ QualType cond = Cond->getType().getCanonicalType();
+ QualType lhs = LHS->getType().getCanonicalType();
+ QualType rhs = RHS->getType().getCanonicalType();
+
+ assert(!cond.isNull() && "ParseConditionalOp(): no conditional type");
+ assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
+ assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
+
+ // C99 6.5.15p2,3
+ return rhs;
+}
+
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS,
ExprTy *RHS) {
- QualType lhs = ((Expr *)LHS)->getType();
- QualType rhs = ((Expr *)RHS)->getType();
-
- assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
- assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
-
- QualType canonType = rhs.getCanonicalType(); // FIXME
- return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, canonType);
+ QualType result = CheckConditionalOperands((Expr *)Cond, (Expr *)LHS,
+ (Expr *)RHS, QuestionLoc);
+ if (result.isNull())
+ return true;
+ return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
}
/// UsualUnaryConversion - Performs various conversions that are common to most
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=39446&r1=39445&r2=39446&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:44:30 2007
@@ -56,8 +56,8 @@
bool isNullPointerConstant() const;
- bool isConstantExpr() const;
- bool isIntegerConstantExpr() const;
+ bool isConstantExpr() const { return isConstantExpr(false); }
+ bool isIntegerConstantExpr() const { return isConstantExpr(true); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@@ -65,6 +65,8 @@
T->getStmtClass() <= lastExprConstant;
}
static bool classof(const Expr *) { return true; }
+private:
+ bool isConstantExpr(bool isIntegerConstant) const;
};
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list