Пример #1
0
//
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped *TIntermediate::addUnaryMath(
    TOperator op, TIntermNode *childNode, const TSourceLoc &line)
{
    TIntermUnary *node;
    TIntermTyped *child = childNode->getAsTyped();

    if (child == NULL)
    {
        mInfoSink.info.message(EPrefixInternalError, line,
                               "Bad type in AddUnaryMath");
        return NULL;
    }

    switch (op)
    {
      case EOpLogicalNot:
        if (child->getType().getBasicType() != EbtBool ||
            child->getType().isMatrix() ||
            child->getType().isArray() ||
            child->getType().isVector())
        {
            return NULL;
        }
        break;

      case EOpPostIncrement:
      case EOpPreIncrement:
      case EOpPostDecrement:
      case EOpPreDecrement:
      case EOpNegative:
      case EOpPositive:
        if (child->getType().getBasicType() == EbtStruct ||
            child->getType().isArray())
        {
            return NULL;
        }
      default:
        break;
    }

    TIntermConstantUnion *childTempConstant = 0;
    if (child->getAsConstantUnion())
        childTempConstant = child->getAsConstantUnion();

    //
    // Make a new node for the operator.
    //
    node = new TIntermUnary(op);
    node->setLine(line);
    node->setOperand(child);

    if (!node->promote(mInfoSink))
        return 0;

    if (childTempConstant)
    {
        TIntermTyped *newChild = childTempConstant->fold(op, 0, mInfoSink);

        if (newChild)
            return newChild;
    }

    return node;
}
Пример #2
0
//
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
{
    TIntermUnary* node;
    TIntermTyped* child = childNode->getAsTyped();

    if (child == 0) {
        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
        return 0;
    }

    switch (op) {
        case EOpLogicalNot:
            if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
                return 0;
            }
            break;

        case EOpPostIncrement:
        case EOpPreIncrement:
        case EOpPostDecrement:
        case EOpPreDecrement:
        case EOpNegative:
            if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
                return 0;
        default: break;
    }

    //
    // Do we need to promote the operand?
    //
    // Note: Implicit promotions were removed from the language.
    //
    TBasicType newType = EbtVoid;
    switch (op) {
        case EOpConstructInt:   newType = EbtInt;   break;
        case EOpConstructBool:  newType = EbtBool;  break;
        case EOpConstructFloat: newType = EbtFloat; break;
        default: break;
    }

    if (newType != EbtVoid) {
        child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
            child->getNominalSize(),
            child->isMatrix(),
            child->isArray()),
            child);
        if (child == 0)
            return 0;
    }

    //
    // For constructors, we are now done, it's all in the conversion.
    //
    switch (op) {
        case EOpConstructInt:
        case EOpConstructBool:
        case EOpConstructFloat:
            return child;
        default: break;
    }

    TIntermConstantUnion *childTempConstant = 0;
    if (child->getAsConstantUnion())
        childTempConstant = child->getAsConstantUnion();

    //
    // Make a new node for the operator.
    //
    node = new TIntermUnary(op);
    if (line == 0)
        line = child->getLine();
    node->setLine(line);
    node->setOperand(child);

    if (! node->promote(infoSink))
        return 0;

    if (childTempConstant)  {
        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);

        if (newChild)
            return newChild;
    }

    return node;
}