Пример #1
0
static void makeAsmTag (
    const vString *const name,
    const vString *const operator,
    const boolean labelCandidate,
    const boolean nameFollows)
{
    if (vStringLength (name) > 0)
    {
        boolean found;
        const AsmKind kind = operatorKind (operator, &found);
        if (found)
        {
            if (kind != K_NONE)
                makeSimpleTag (name, AsmKinds, kind);
        }
        else if (isDefineOperator (operator))
        {
            if (! nameFollows)
                makeSimpleTag (name, AsmKinds, K_DEFINE);
        }
        else if (labelCandidate)
        {
            operatorKind (name, &found);
            if (! found)
                makeSimpleTag (name, AsmKinds, K_LABEL);
        }
    }
}
Пример #2
0
void UnaryOperator::doPrint(PrintContext &context) const {
    switch (operatorKind()) {
        case DEREFERENCE:
            context.out() << '*';
            break;
        case REFERENCE:
            context.out() << '&';
            break;
        case BITWISE_NOT:
            context.out() << '~';
            break;
        case LOGICAL_NOT:
            context.out() << '!';
            break;
        case NEGATION:
            context.out() << '-';
            break;
        case PREFIX_INCREMENT:
            context.out() << "++";
            break;
        case PREFIX_DECREMENT:
            context.out() << "--";
            break;
        default:
            unreachable();
            break;
    }

    int precedence = this->precedence();
    int operandPrecedence = operand()->precedence();

    int absPrecedence = abs(precedence);
    int absOperandPrecedence = abs(operandPrecedence);

    bool operandInBraces = absOperandPrecedence > absPrecedence;

    /* Avoid too many minuses in a row. */
    if (operatorKind() == NEGATION || operatorKind() == PREFIX_DECREMENT) {
        if (auto unary = operand()->as<UnaryOperator>()) {
            if (unary->operatorKind() == NEGATION || unary->operatorKind() == PREFIX_DECREMENT) {
                operandInBraces = true;
            }
        }
    }

    if (operandInBraces) {
        context.out() << '(';
    }
    operand()->print(context);
    if (operandInBraces) {
        context.out() << ')';
    }
}
Пример #3
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;
    }
}
Пример #4
0
int UnaryOperator::precedence() const {
    switch (operatorKind()) {
        case DEREFERENCE:
        case REFERENCE:
        case BITWISE_NOT:
        case LOGICAL_NOT:
        case NEGATION:
        case PREFIX_INCREMENT:
        case PREFIX_DECREMENT:
            return -3;
        default:
            unreachable();
            return 0;
    }
}
Пример #5
0
const Type *UnaryOperator::getType() const {
    const Type *operandType = operand()->getType();
    switch (operatorKind()) {
        case REFERENCE: {
            return tree().makePointerType(operandType);
        }
        case DEREFERENCE:
            if (const PointerType *pointerType = operandType->as<PointerType>()) {
                return pointerType->pointeeType();
            } else {
                return tree().makeErroneousType();
            }
            break;
        case BITWISE_NOT:
            if (operandType->isInteger()) {
                return tree().integerPromotion(operandType);
            } else {
                return tree().makeErroneousType();
            }
        case LOGICAL_NOT:
            if (operandType->isScalar()) {
                return tree().makeIntegerType(tree().intSize(), false);
            } else {
                return tree().makeErroneousType();
            }
            break;
        case NEGATION: {
            if (operandType->isInteger() || operandType->isFloat()) {
                return operandType;
            } else {
                return tree().makeErroneousType();
            }
            break;
        }
        case PREFIX_INCREMENT:
        case PREFIX_DECREMENT:
            if (operandType->isScalar()) {
                return operandType;
            } else {
                return tree().makeErroneousType();
            }
            break;
        default:
            unreachable();
            break;
    }
    return NULL;
}
Пример #6
0
static void makeAsmTag (
		const vString *const name,
		const vString *const operator,
		const bool labelCandidate,
		const bool nameFollows,
		const bool directive,
		unsigned int *lastMacroCorkIndex)
{
	if (vStringLength (name) > 0)
	{
		bool found;
		const AsmKind kind = operatorKind (operator, &found);
		if (found)
		{
			if (kind > K_NONE)
				makeSimpleTag (name, kind);
		}
		else if (isDefineOperator (operator))
		{
			if (! nameFollows)
				makeSimpleTag (name, K_DEFINE);
		}
		else if (labelCandidate)
		{
			operatorKind (name, &found);
			if (! found)
				makeSimpleTag (name, K_LABEL);
		}
		else if (directive)
		{
			bool found_dummy;
			const AsmKind kind_for_directive = operatorKind (name, &found_dummy);
			tagEntryInfo *macro_tag;

			switch (kind_for_directive)
			{
			case K_NONE:
				break;
			case K_MACRO:
				*lastMacroCorkIndex = makeSimpleTag (operator,
													 kind_for_directive);
				break;
			case K_PSUEDO_MACRO_END:
				if (*lastMacroCorkIndex != CORK_NIL)
				{
					macro_tag = getEntryInCorkQueue (*lastMacroCorkIndex);
					macro_tag->extensionFields.endLine = getInputLineNumber ();
					*lastMacroCorkIndex = CORK_NIL;
				}
				break;
			case K_SECTION:
				makeSimpleRefTag (operator,
								  kind_for_directive,
								  ASM_SECTION_PLACEMENT);
				break;
			default:
				makeSimpleTag (operator, kind_for_directive);
			}
		}
	}
}