Expression *UnaryOperator::rewrite() { rewriteChild(operand_); switch (operatorKind()) { case DEREFERENCE: { if (UnaryOperator *unary = operand()->as<UnaryOperator>()) { if (unary->operatorKind() == REFERENCE) { return unary->releaseOperand().release(); } } return this; } case LOGICAL_NOT: { while (Typecast *typecast = operand()->as<Typecast>()) { if (typecast->type()->isScalar() && typecast->operand()->getType()->isScalar()) { setOperand(typecast->releaseOperand()); } else { break; } } if (BinaryOperator *binary = operand()->as<BinaryOperator>()) { switch (binary->operatorKind()) { case BinaryOperator::EQ: binary->setOperatorKind(BinaryOperator::NEQ); return releaseOperand().release(); case BinaryOperator::NEQ: binary->setOperatorKind(BinaryOperator::EQ); return releaseOperand().release(); case BinaryOperator::LT: binary->setOperatorKind(BinaryOperator::GEQ); return releaseOperand().release(); case BinaryOperator::LEQ: binary->setOperatorKind(BinaryOperator::GT); return releaseOperand().release(); case BinaryOperator::GT: binary->setOperatorKind(BinaryOperator::LEQ); return releaseOperand().release(); case BinaryOperator::GEQ: binary->setOperatorKind(BinaryOperator::LT); return releaseOperand().release(); default: break; } } if (UnaryOperator *unary = operand()->as<UnaryOperator>()) { if (unary->operatorKind() == LOGICAL_NOT) { if (unary->operand()->getType()->size() == 1) { return unary->releaseOperand().release(); } } } return this; } default: return this; } }
While *While::rewrite() { assert(condition_); assert(body_); condition_ = simplifyBooleanExpression(std::move(condition_)); rewriteChild(body_); return this; }
Expression *Typecast::rewrite() { rewriteChild(operand_); /* Convert cast of pointer to a structure to a cast of pointer to its first field. */ if (type_->isPointer() && !type_->isStructurePointer()) { if (const PointerType *pointerType = operand()->getType()->as<PointerType>()) { if (const StructType *structType = pointerType->pointeeType()->as<StructType>()) { if (const MemberDeclaration *member = structType->getMember(0)) { setOperand(std::make_unique<UnaryOperator>(tree(), UnaryOperator::REFERENCE, std::make_unique<MemberAccessOperator>(tree(), MemberAccessOperator::ARROW, releaseOperand(), member))); } } } } /* * (int32_t*)(int64_t)expr -> (int32_t*)expr */ if (type_->isScalar()) { if (Typecast *typecast = operand()->as<Typecast>()) { const Type *operandType = typecast->operand()->getType(); if (typecast->type()->isScalar() && operandType->isScalar() && type_->size() == typecast->type()->size() && typecast->type()->size() == operandType->size()) { setOperand(typecast->releaseOperand()); } } } /* This really must be the last rule. */ if (type_ == operand()->getType()) { return releaseOperand().release(); } return this; }
Goto *Goto::rewrite() { rewriteChild(destination_); return this; }