diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-03-23 04:38:34 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-03-23 04:38:34 +0000 |
commit | a1f47c447a919c6a05c63801cb6a52c4c288e2cc (patch) | |
tree | 443e435a1fee3f433793fc2892fcf36ce3ce5704 /lib/AST/ExprConstant.cpp | |
parent | c110c545810670871f54d0e999b5384ca0d6519d (diff) |
Minor enhancements to Evaluate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67503 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a0ef7460c5..529b4d49c5 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -71,7 +71,7 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { return false; Result = !FloatResult.isZero(); return true; - } else if (E->getType()->isPointerType()) { + } else if (E->getType()->hasPointerRepresentation()) { APValue PointerResult; if (!EvaluatePointer(E, PointerResult, Info)) return false; @@ -79,8 +79,19 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { // the check look like? Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset(); return true; + } else if (E->getType()->isAnyComplexType()) { + APValue ComplexResult; + if (!EvaluateComplex(E, ComplexResult, Info)) + return false; + if (ComplexResult.isComplexFloat()) { + Result = !ComplexResult.getComplexFloatReal().isZero() || + !ComplexResult.getComplexFloatImag().isZero(); + } else { + Result = ComplexResult.getComplexIntReal().getBoolValue() || + ComplexResult.getComplexIntImag().getBoolValue(); + } + return true; } - // FIXME: Handle pointer-like types, complex types return false; } @@ -890,21 +901,22 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APValue LHSValue; if (!EvaluatePointer(E->getLHS(), LHSValue, Info)) return false; - + APValue RHSValue; if (!EvaluatePointer(E->getRHS(), RHSValue, Info)) return false; - - // FIXME: Is this correct? What if only one of the operands has a base? + + // Reject any bases; this is conservative, but good enough for + // common uses if (LHSValue.getLValueBase() || RHSValue.getLValueBase()) return false; - + const QualType Type = E->getLHS()->getType(); const QualType ElementType = Type->getAsPointerType()->getPointeeType(); uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset(); D /= Info.Ctx.getTypeSize(ElementType) / 8; - + return Success(D, E); } } @@ -980,20 +992,20 @@ unsigned IntExprEvaluator::GetAlignOfType(QualType T) { // __alignof__(void) = 1 as a gcc extension. if (Ty->isVoidType()) return 1; - + // GCC extension: alignof(function) = 4. // FIXME: AlignOf shouldn't be unconditionally 4! It should listen to the // attribute(align) directive. if (Ty->isFunctionType()) return 4; - + if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty)) return GetAlignOfType(QualType(EXTQT->getBaseType(), 0)); // alignof VLA/incomplete array. if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty)) return GetAlignOfType(VAT->getElementType()); - + // sizeof (objc class)? if (isa<ObjCInterfaceType>(Ty)) return 1; // FIXME: This probably isn't right. @@ -1010,7 +1022,7 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) { // to 1 in those cases. if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) return Info.Ctx.getDeclAlignInBytes(DRE->getDecl()); - + if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl()); @@ -1030,14 +1042,14 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { else return Success(GetAlignOfExpr(E->getArgumentExpr()), E); } - + QualType SrcTy = E->getTypeOfArgument(); // 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; |