forked from OSchip/llvm-project
parent
c4169cebe3
commit
9e0e7096a3
|
@ -2091,12 +2091,13 @@ public:
|
|||
bool VisitCastExpr(CastExpr *E);
|
||||
|
||||
bool VisitBinaryOperator(const BinaryOperator *E);
|
||||
bool VisitUnaryOperator(const UnaryOperator *E);
|
||||
bool VisitConditionalOperator(const ConditionalOperator *E);
|
||||
bool VisitChooseExpr(const ChooseExpr *E)
|
||||
{ return Visit(E->getChosenSubExpr(Info.Ctx)); }
|
||||
bool VisitUnaryExtension(const UnaryOperator *E)
|
||||
{ return Visit(E->getSubExpr()); }
|
||||
// FIXME Missing: unary +/-/~, binary div, ImplicitValueInitExpr,
|
||||
// conditional ?:, comma
|
||||
// FIXME Missing: ImplicitValueInitExpr
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -2227,6 +2228,17 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) {
|
|||
}
|
||||
|
||||
bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||
if (E->getOpcode() == BO_Comma) {
|
||||
if (!Visit(E->getRHS()))
|
||||
return false;
|
||||
|
||||
// If we can't evaluate the LHS, it might have side effects;
|
||||
// conservatively mark it.
|
||||
if (!E->getLHS()->isEvaluatable(Info.Ctx))
|
||||
Info.EvalResult.HasSideEffects = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (!Visit(E->getLHS()))
|
||||
return false;
|
||||
|
||||
|
@ -2291,11 +2303,97 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
|||
LHS.getComplexIntImag() * RHS.getComplexIntReal());
|
||||
}
|
||||
break;
|
||||
case BO_Div:
|
||||
if (Result.isComplexFloat()) {
|
||||
ComplexValue LHS = Result;
|
||||
APFloat &LHS_r = LHS.getComplexFloatReal();
|
||||
APFloat &LHS_i = LHS.getComplexFloatImag();
|
||||
APFloat &RHS_r = RHS.getComplexFloatReal();
|
||||
APFloat &RHS_i = RHS.getComplexFloatImag();
|
||||
APFloat &Res_r = Result.getComplexFloatReal();
|
||||
APFloat &Res_i = Result.getComplexFloatImag();
|
||||
|
||||
APFloat Den = RHS_r;
|
||||
Den.multiply(RHS_r, APFloat::rmNearestTiesToEven);
|
||||
APFloat Tmp = RHS_i;
|
||||
Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
|
||||
Den.add(Tmp, APFloat::rmNearestTiesToEven);
|
||||
|
||||
Res_r = LHS_r;
|
||||
Res_r.multiply(RHS_r, APFloat::rmNearestTiesToEven);
|
||||
Tmp = LHS_i;
|
||||
Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
|
||||
Res_r.add(Tmp, APFloat::rmNearestTiesToEven);
|
||||
Res_r.divide(Den, APFloat::rmNearestTiesToEven);
|
||||
|
||||
Res_i = LHS_i;
|
||||
Res_i.multiply(RHS_r, APFloat::rmNearestTiesToEven);
|
||||
Tmp = LHS_r;
|
||||
Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
|
||||
Res_i.subtract(Tmp, APFloat::rmNearestTiesToEven);
|
||||
Res_i.divide(Den, APFloat::rmNearestTiesToEven);
|
||||
} else {
|
||||
if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0) {
|
||||
// FIXME: what about diagnostics?
|
||||
return false;
|
||||
}
|
||||
ComplexValue LHS = Result;
|
||||
APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
|
||||
RHS.getComplexIntImag() * RHS.getComplexIntImag();
|
||||
Result.getComplexIntReal() =
|
||||
(LHS.getComplexIntReal() * RHS.getComplexIntReal() +
|
||||
LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
|
||||
Result.getComplexIntImag() =
|
||||
(LHS.getComplexIntImag() * RHS.getComplexIntReal() -
|
||||
LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
||||
// Get the operand value into 'Result'.
|
||||
if (!Visit(E->getSubExpr()))
|
||||
return false;
|
||||
|
||||
switch (E->getOpcode()) {
|
||||
default:
|
||||
// FIXME: what about diagnostics?
|
||||
return false;
|
||||
case UO_Extension:
|
||||
return true;
|
||||
case UO_Plus:
|
||||
// The result is always just the subexpr.
|
||||
return true;
|
||||
case UO_Minus:
|
||||
if (Result.isComplexFloat()) {
|
||||
Result.getComplexFloatReal().changeSign();
|
||||
Result.getComplexFloatImag().changeSign();
|
||||
}
|
||||
else {
|
||||
Result.getComplexIntReal() = -Result.getComplexIntReal();
|
||||
Result.getComplexIntImag() = -Result.getComplexIntImag();
|
||||
}
|
||||
return true;
|
||||
case UO_Not:
|
||||
if (Result.isComplexFloat())
|
||||
Result.getComplexFloatImag().changeSign();
|
||||
else
|
||||
Result.getComplexIntImag() = -Result.getComplexIntImag();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ComplexExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
|
||||
bool Cond;
|
||||
if (!HandleConversionToBool(E->getCond(), Cond, Info))
|
||||
return false;
|
||||
|
||||
return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Top level Expr::Evaluate method.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -53,3 +53,15 @@ void test4(_Complex float *x) {
|
|||
void test5(_Complex int *x) {
|
||||
(*x)++;
|
||||
}
|
||||
|
||||
int i1[(2+3i)*(5+7i) == 29i-11 ? 1 : -1];
|
||||
int i2[(29i-11)/(5+7i) == 2+3i ? 1 : -1];
|
||||
int i3[-(2+3i) == +(-3i-2) ? 1 : -1];
|
||||
int i4[~(2+3i) == 2-3i ? 1 : -1];
|
||||
int i5[(3i == -(-3i) ? ((void)3, 1i - 1) : 0) == 1i - 1 ? 1 : -1];
|
||||
|
||||
int f1[(2.0+3.0i)*(5.0+7.0i) == 29.0i-11.0 ? 1 : -1];
|
||||
int f2[(29.0i-11.0)/(5.0+7.0i) == 2.0+3.0i ? 1 : -1];
|
||||
int f3[-(2.0+3.0i) == +(-3.0i-2.0) ? 1 : -1];
|
||||
int f4[~(2.0+3.0i) == 2.0-3.0i ? 1 : -1];
|
||||
int f5[(3.0i == -(-3.0i) ? ((void)3.0, __extension__ (1.0i - 1.0)) : 0) == 1.0i - 1.0 ? 1 : -1];
|
||||
|
|
Loading…
Reference in New Issue