[cfe-commits] r65038 - /cfe/trunk/lib/AST/ExprConstant.cpp
Daniel Dunbar
daniel at zuster.org
Thu Feb 19 01:06:46 PST 2009
Author: ddunbar
Date: Thu Feb 19 03:06:44 2009
New Revision: 65038
URL: http://llvm.org/viewvc/llvm-project?rev=65038&view=rev
Log:
Add IntExprEvaluator::Success method.
- Handles assignment to Result with appropriate type.
- Simplifies & encapsulates most direct handling of the Result value;
prep for allowing IntExprEvaluator to deal with LValue APValues.
- No intended functionality change.
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=65038&r1=65037&r2=65038&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Feb 19 03:06:44 2009
@@ -462,26 +462,31 @@
IntExprEvaluator(EvalInfo &info, APSInt &result)
: Info(info), Result(result) {}
- unsigned getIntTypeSizeInBits(QualType T) const {
- return (unsigned)Info.Ctx.getIntWidth(T);
- }
-
bool Extension(SourceLocation L, diag::kind D, const Expr *E) {
Info.EvalResult.DiagLoc = L;
Info.EvalResult.Diag = D;
Info.EvalResult.DiagExpr = E;
return true; // still a constant.
}
-
+
+ bool Success(const llvm::APInt &I, const Expr *E) {
+ Result = I;
+ Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
+ return true;
+ }
+
+ bool Success(uint64_t Value, const Expr *E) {
+ Result = Info.Ctx.MakeIntValue(Value, E->getType());
+ return true;
+ }
+
bool Error(SourceLocation L, diag::kind D, const Expr *E) {
// If this is in an unevaluated portion of the subexpression, ignore the
// error.
if (Info.ShortCircuit) {
// If error is ignored because the value isn't evaluated, get the real
// type at least to prevent errors downstream.
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(0, E);
}
// Take the first error.
@@ -509,26 +514,20 @@
bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
bool VisitIntegerLiteral(const IntegerLiteral *E) {
- Result = E->getValue();
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(E->getValue(), E);
}
bool VisitCharacterLiteral(const CharacterLiteral *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->getValue();
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(E->getValue(), E);
}
bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
// Per gcc docs "this built-in function ignores top level
// qualifiers". We need to use the canonical version to properly
// be able to strip CRV qualifiers from the type.
QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
- Result = Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
- T1.getUnqualifiedType());
- return true;
+ return Success(Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
+ T1.getUnqualifiedType()),
+ E);
}
bool VisitDeclRefExpr(const DeclRefExpr *E);
bool VisitCallExpr(const CallExpr *E);
@@ -540,28 +539,19 @@
bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->getValue();
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(E->getValue(), E);
}
bool VisitGNUNullExpr(const GNUNullExpr *E) {
- Result = APSInt::getNullValue(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(0, E);
}
bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
- Result = APSInt::getNullValue(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success(0, E);
}
bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->EvaluateTrait();
- return true;
+ return Success(E->EvaluateTrait(), E);
}
private:
@@ -653,21 +643,16 @@
}
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
-
switch (E->isBuiltinCall(Info.Ctx)) {
default:
return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
case Builtin::BI__builtin_classify_type:
- Result.setIsSigned(true);
- Result = EvaluateBuiltinClassifyType(E);
- return true;
+ return Success(EvaluateBuiltinClassifyType(E), E);
case Builtin::BI__builtin_constant_p:
// __builtin_constant_p always has one operand: it returns true if that
// operand can be folded, false otherwise.
- Result = E->getArg(0)->isEvaluatable(Info.Ctx);
- return true;
+ return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
}
}
@@ -698,9 +683,7 @@
// evaluating the RHS: 0 && X -> 0, 1 || X -> 1
if (lhsResult == (E->getOpcode() == BinaryOperator::LOr) ||
!lhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- Result = lhsResult;
+ Result = Info.Ctx.MakeIntValue(lhsResult, E->getType());
Info.ShortCircuit++;
bool rhsEvaluated = HandleConversionToBool(E->getRHS(), rhsResult, Info);
@@ -715,13 +698,10 @@
}
if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
if (E->getOpcode() == BinaryOperator::LOr)
- Result = lhsResult || rhsResult;
+ return Success(lhsResult || rhsResult, E);
else
- Result = lhsResult && rhsResult;
- return true;
+ return Success(lhsResult && rhsResult, E);
}
} else {
if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
@@ -729,15 +709,11 @@
// is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
if (rhsResult == (E->getOpcode() == BinaryOperator::LOr) ||
!rhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- Result = rhsResult;
-
- // Since we werent able to evaluate the left hand side, it
+ // Since we weren't able to evaluate the left hand side, it
// must have had side effects.
Info.EvalResult.HasSideEffects = true;
-
- return true;
+
+ return Success(rhsResult, E);
}
}
}
@@ -764,31 +740,27 @@
APFloat::cmpResult CR_i =
LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
if (E->getOpcode() == BinaryOperator::EQ)
- Result = (CR_r == APFloat::cmpEqual &&
- CR_i == APFloat::cmpEqual);
- else if (E->getOpcode() == BinaryOperator::NE)
- Result = ((CR_r == APFloat::cmpGreaterThan ||
- CR_r == APFloat::cmpLessThan) &&
- (CR_i == APFloat::cmpGreaterThan ||
- CR_i == APFloat::cmpLessThan));
- else
- assert(0 && "Invalid complex compartison.");
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success((CR_r == APFloat::cmpEqual &&
+ CR_i == APFloat::cmpEqual), E);
+ else {
+ assert(E->getOpcode() == BinaryOperator::NE &&
+ "Invalid complex comparison.");
+ return Success(((CR_r == APFloat::cmpGreaterThan ||
+ CR_r == APFloat::cmpLessThan) &&
+ (CR_i == APFloat::cmpGreaterThan ||
+ CR_i == APFloat::cmpLessThan)), E);
+ }
} else {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
if (E->getOpcode() == BinaryOperator::EQ)
- Result = (LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
- LHS.getComplexIntImag() == RHS.getComplexIntImag());
- else if (E->getOpcode() == BinaryOperator::NE)
- Result = (LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
- LHS.getComplexIntImag() != RHS.getComplexIntImag());
- else
- assert(0 && "Invalid complex compartison.");
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
+ return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
+ LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
+ else {
+ assert(E->getOpcode() == BinaryOperator::NE &&
+ "Invalid compex comparison.");
+ return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
+ LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
+ }
}
}
@@ -804,33 +776,24 @@
APFloat::cmpResult CR = LHS.compare(RHS);
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
-
switch (E->getOpcode()) {
default:
assert(0 && "Invalid binary operator!");
case BinaryOperator::LT:
- Result = CR == APFloat::cmpLessThan;
- break;
+ return Success(CR == APFloat::cmpLessThan, E);
case BinaryOperator::GT:
- Result = CR == APFloat::cmpGreaterThan;
- break;
+ return Success(CR == APFloat::cmpGreaterThan, E);
case BinaryOperator::LE:
- Result = CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual;
- break;
+ return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
case BinaryOperator::GE:
- Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual;
- break;
+ return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
+ E);
case BinaryOperator::EQ:
- Result = CR == APFloat::cmpEqual;
- break;
+ return Success(CR == APFloat::cmpEqual, E);
case BinaryOperator::NE:
- Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpLessThan;
- break;
+ return Success(CR == APFloat::cmpGreaterThan
+ || CR == APFloat::cmpLessThan, E);
}
-
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
}
if (E->getOpcode() == BinaryOperator::Sub) {
@@ -853,11 +816,7 @@
uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
D /= Info.Ctx.getTypeSize(ElementType) / 8;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = D;
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
-
- return true;
+ return Success(D, E);
}
}
if (!LHSTy->isIntegralType() ||
@@ -869,15 +828,11 @@
}
// The LHS of a constant expr is always evaluated and needed.
- llvm::APSInt RHS(32);
if (!Visit(E->getLHS())) {
return false; // error in subexpression.
}
-
- // FIXME Maybe we want to succeed even where we can't evaluate the
- // right side of LAnd/LOr?
- // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
+ llvm::APSInt RHS;
if (!EvaluateInteger(E->getRHS(), RHS, Info))
return false;
@@ -908,38 +863,12 @@
Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
break;
- case BinaryOperator::LT:
- Result = Result < RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::GT:
- Result = Result > RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LE:
- Result = Result <= RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::GE:
- Result = Result >= RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::EQ:
- Result = Result == RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::NE:
- Result = Result != RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LAnd:
- Result = Result != 0 && RHS != 0;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LOr:
- Result = Result != 0 || RHS != 0;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
+ case BinaryOperator::LT: return Success(Result < RHS, E);
+ case BinaryOperator::GT: return Success(Result > RHS, E);
+ case BinaryOperator::LE: return Success(Result <= RHS, E);
+ case BinaryOperator::GE: return Success(Result >= RHS, E);
+ case BinaryOperator::EQ: return Success(Result == RHS, E);
+ case BinaryOperator::NE: return Success(Result != RHS, E);
}
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
@@ -1002,36 +931,25 @@
/// expression's type.
bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
QualType DstTy = E->getType();
- // Return the result in the right width.
- Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
- Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
// Handle alignof separately.
if (!E->isSizeOf()) {
if (E->isArgumentType())
- Result = GetAlignOfType(E->getArgumentType());
+ return Success(GetAlignOfType(E->getArgumentType()), E);
else
- Result = GetAlignOfExpr(E->getArgumentExpr());
- return true;
+ return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
}
QualType SrcTy = E->getTypeOfArgument();
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
- if (SrcTy->isVoidType()) {
- Result = 1;
- return true;
- }
+ // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
+ // extension.
+ if (SrcTy->isVoidType() || SrcTy->isFunctionType())
+ return Success(1, E);
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
if (!SrcTy->isConstantSizeType())
return false;
-
- // GCC extension: sizeof(function) = 1.
- if (SrcTy->isFunctionType()) {
- Result = 1;
- return true;
- }
if (SrcTy->isObjCInterfaceType()) {
// Slightly unusual case: the size of an ObjC interface type is the
@@ -1044,29 +962,21 @@
// Get information about the size.
unsigned CharSize = Info.Ctx.Target.getCharWidth();
- Result = Info.Ctx.getTypeSize(SrcTy) / CharSize;
- return true;
+ return Success(Info.Ctx.getTypeSize(SrcTy) / CharSize, E);
}
bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
// Special case unary operators that do not need their subexpression
// evaluated. offsetof/sizeof/alignof are all special.
- if (E->isOffsetOfOp()) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->evaluateOffsetOf(Info.Ctx);
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
- }
+ if (E->isOffsetOfOp())
+ return Success(E->evaluateOffsetOf(Info.Ctx), E);
if (E->getOpcode() == UnaryOperator::LNot) {
// LNot's operand isn't necessarily an integer, so we handle it specially.
bool bres;
if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
return false;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- Result = !bres;
- return true;
+ return Success(!bres, E);
}
// Get the operand value into 'Result'.
@@ -1081,6 +991,7 @@
case UnaryOperator::Extension:
// FIXME: Should extension allow i-c-e extension expressions in its scope?
// If so, we could clear the diagnostic ID.
+ break;
case UnaryOperator::Plus:
// The result is always just the subexpr.
break;
@@ -1102,16 +1013,11 @@
Expr *SubExpr = E->getSubExpr();
QualType DestType = E->getType();
- unsigned DestWidth = getIntTypeSizeInBits(DestType);
-
if (DestType->isBooleanType()) {
bool BoolResult;
if (!HandleConversionToBool(SubExpr, BoolResult, Info))
return false;
- Result.zextOrTrunc(DestWidth);
- Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- Result = BoolResult;
- return true;
+ return Success(BoolResult, E);
}
// Handle simple integer->integer casts.
@@ -1132,10 +1038,7 @@
if (LV.getLValueBase())
return false;
- Result.extOrTrunc(DestWidth);
- Result = LV.getLValueOffset();
- Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- return true;
+ return Success(LV.getLValueOffset(), E);
}
if (!SubExpr->getType()->isRealFloatingType())
More information about the cfe-commits
mailing list