Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
While *While::rewrite() {
    assert(condition_);
    assert(body_);

    condition_ = simplifyBooleanExpression(std::move(condition_));
    rewriteChild(body_);

    return this;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
Goto *Goto::rewrite() {
    rewriteChild(destination_);
    return this;
}