analnode.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,101 行 · 第 1/5 页

C
2,101
字号
{
    if( flags & PTF_LVALUE ) {
        if( NULL == TypeReference( type ) ) {
            type = MakeReferenceTo( type );
        }
    }
    expr = NodeConvert( type, expr );
    expr = NodeSetType( expr, type, flags );
    return expr;
}


PTREE NodeSetBooleanType(       // SET NODE TO TYPE OF A REL-OP EXPR
    PTREE expr )                // - expression
{
    expr->flags |= PTF_BOOLEAN;
    expr->type = GetBasicType( TYP_BOOL );
    return expr;
}


PTREE NodeCompareToZero(        // MAKE A COMPARE-TO-ZERO NODE, IF REQ'D
    PTREE expr )
{
    PTREE zero;                 // - constant node (contains zero)
    PTREE operand;              // - operand to be compared
    TYPE type;                  // - expression type, unmodified

    if( expr->flags & PTF_BOOLEAN ) {
        return expr;
    }
    if( PTreeOpFlags( expr ) & PTO_BOOLEAN ) {
        return expr;
    }
    type = TypeReferenced( expr->type );
    type = TypedefModifierRemoveOnly( type );
    if( type->id == TYP_VOID ) {
        PTreeErrorExpr( expr, ERR_EXPR_IS_VOID );
    } else {
        if( ( NULL == StructType( type ) )
          &&( NULL == MemberPtrType( type ) ) ) {
            expr = NodeRvalue( expr );
            if( ! ArithType( type ) ) {
                // may be &fn or array decay to a pointer
                type = expr->type;
            }
        } else {
            type = GetBasicType( TYP_SINT );
        }
        operand = expr;
        zero = NodeIntegralConstant( 0, type );
        expr = NodeBinary( CO_NE, operand, zero );
        expr = PTreeCopySrcLocation( expr, operand );
        expr = NodeSetBooleanType( expr );
        expr = ConvertBoolean( expr );
    }
    return expr;
}

static CNV_DIAG diagConvertToBool = // DIAGNOSIS FOR CONVERT-TO-BOOL NODE
{   ERR_IMPLICIT_CAST_ILLEGAL   // - impossible
,   ERR_CALL_WATCOM             // - ambiguous
,   ERR_CALL_WATCOM
,   ERR_CALL_WATCOM             // - protected violation
,   ERR_CALL_WATCOM             // - private violation
};

PTREE NodeConvertToBool(        // MAKE A CONVERT-TO-BOOL NODE, IF REQ'D
    PTREE expr )
{
    PTREE zero;                 // - constant node (contains zero)
    PTREE operand;              // - operand to be compared
    TYPE type;                  // - expression type, unmodified

    if( expr->flags & PTF_BOOLEAN ) {
        return expr;
    }
    if( PTreeOpFlags( expr ) & PTO_BOOLEAN ) {
        return expr;
    }
    type = TypeReferenced( expr->type );
    type = TypedefModifierRemoveOnly( type );
    if( type->id == TYP_VOID ) {
        PTreeErrorExpr( expr, ERR_EXPR_IS_VOID );
    } else if( type->id == TYP_CLASS ) {
        TYPE bool_type = GetBasicType( TYP_BOOL );
        expr = CastImplicit( expr, bool_type, CNV_EXPR, &diagConvertToBool );
    } else {
        operand = expr;
        zero = NodeIntegralConstant( 0, GetBasicType( TYP_SINT ) );
        expr = NodeBinary( CO_NE, expr, zero );
        expr = PTreeCopySrcLocation( expr, operand );
        expr = AnalyseOperator( expr );
    }
    return expr;
}


PTREE NodeRemoveCasts(          // REMOVE CASTING FROM NODE
    PTREE node )                // - starting node
{
    while( NodeIsBinaryOp( node, CO_CONVERT ) ) {
        node = PTreeOpRight( node );
    }
    return node;
}


PTREE NodeRemoveCastsCommas(    // REMOVE COMMAS, DTORING, CASTING FROM NODE
    PTREE node )                // - starting node
{
    PTREE not_used;             // - dtoring, not used

    return *NodeReturnSrc( &node, &not_used );
}


PTREE NodeSymbolNoRef(          // FILL IN NODE FOR A SYMBOL, NO REF. SETTING
    PTREE expr,                 // - node
    SYMBOL sym,                 // - symbol
    SEARCH_RESULT *result )     // - search result
{
    if( NULL == expr ) {
        expr = PTreeAlloc();
    }
    expr->u.symcg.result = result;
    expr->u.symcg.symbol = sym;
    expr->op = PT_SYMBOL;
    expr->flags |= PTF_LVALUE | PTF_LV_CHECKED;
    expr->type = sym->sym_type;
    expr->cgop = CO_NAME_NORMAL;
    if( result != NULL ) {
        ScopeResultErrLocn( result, &expr->locn );
        if( result->sym != NULL ) {
            expr->cgop = CO_NAME_CONVERT;
        }
    }
    return expr;
}


PTREE NodeSymbol(               // CONVERT NODE TO BE SYMBOL
    PTREE expr,                 // - node
    SYMBOL sym,                 // - symbol
    SEARCH_RESULT *result )     // - search result
{
    sym = SymMarkRefed( sym );
    return NodeSymbolNoRef( expr, sym, result );
}


PTREE NodeSymbolCallee(         // MAKE SYMBOL FOR A CALLEE
    PTREE expr,                 // - node
    SYMBOL sym,                 // - symbol
    SEARCH_RESULT *result )     // - search result
{
    if( ! SymIsVirtual( sym ) ) {
        sym = SymMarkRefed( sym );
    }
    return NodeSymbolNoRef( expr, sym, result );
}


PTREE MakeNodeSymbol(           // MAKE PT_SYMBOL NODE FROM SYMBOL
    SYMBOL sym )                // - symbol
{
    sym = SymMarkRefed( sym );
    if( NULL != StructType( sym->sym_type ) ) {
        sym->flag |= PTF_MEMORY_EXACT;
    }
    return NodeSymbolNoRef( NULL, sym, NULL );
}


PTREE NodeMakeCallee(           // MAKE A CALLEE NODE
    SYMBOL func )               // - function
{
    if( ! SymIsVirtual( func ) ) {
        func = SymMarkRefed( func );
    }
    return NodeSymbolNoRef( NULL, func, NULL );
}


PTREE NodeGetConstantNode(      // RETURN CONSTANT-INT NODE
    PTREE node )                // - node
{
    for( ; ; ) {
        if( NodeIsBinaryOp( node, CO_CONVERT ) ) {
            if( NULL == IntegralType( NodeType( node ) ) ) {
                node = NULL;
                break;
            }
            node = node->u.subtree[1];
        } else if( NodeIsBinaryOp( node, CO_COMMA ) ) {
            node = node->u.subtree[1];
        } else {
            break;
        }
    }
    if( node != NULL )
    switch( node->op ) {
      case PT_INT_CONSTANT :
        if( NULL == IntegralType( NodeType( node ) ) ) {
            node = NULL;
        }
        break;
      case PT_SYMBOL :
        if( SymIsConstantInt( node->u.symcg.symbol ) ) {
            node = PTreeOpRight( node );
        } else {
            node = NULL;
        }
        break;
      default :
        node = NULL;
        break;
    }
    return node;
}


boolean NodeIsConstantInt(      // TEST IF A CONSTANT INT NODE
    PTREE node )                // - node
{
    boolean retn;               // - TRUE ==> is zero constant

    if( node == NULL ) {
        retn = FALSE;
    } else {
        node = NodeRemoveCasts( PTreeOp( &node ) );
        switch( node->op ) {
          case PT_INT_CONSTANT :
            retn = ( NULL != IntegralType( node->type ) );
            break;
          case PT_SYMBOL :
            retn = SymIsConstantInt( node->u.symcg.symbol );
            break;
          default :
            retn = FALSE;
            break;
        }
    }
    return retn;
}


boolean NodeIsConstant(         // TEST IF NODE IS A CONSTANT
    PTREE node )                // - node
{
    boolean retn;               // - TRUE ==> is constant

    if( TypeIsConst( NodeType( node ) ) ) {
        retn = TRUE;
    } else {
        switch( node->op ) {
          case PT_INT_CONSTANT :       // these are typed w/o TF1_CONST
          case PT_STRING_CONSTANT :
          case PT_FLOATING_CONSTANT :
            retn = TRUE;
            break;
          default :
            retn = FALSE;
            break;
        }
    }
    return retn;
}


unsigned long NodeConstantValue(// GET CONSTANT VALUE FOR A NODE
    PTREE node )                // - a constant node
{
    SYMBOL sym;                 // - symbol for node
    unsigned long retn;         // - return value

    node = NodeRemoveCasts( node );
    switch( node->op ) {
      case PT_INT_CONSTANT :
        retn = node->u.int_constant;
        break;
      case PT_SYMBOL :
        sym = node->u.symcg.symbol;
        retn = sym->u.sval;
        break;
      DbgDefault( "non-constant node passed to NodeConstantValue" );
    }
    return retn;
}


static boolean nodeGetConstant  // TEST IF CONSTANT AND GET VALUE
    ( PTREE node                // - potential constant node
    , INT_CONSTANT* pval )      // - addr[ value ]
{
    boolean retn;               // - return: TRUE ==> is integral constant
    SYMBOL sym;                 // - symbol for node

    if( node == NULL ) {
        retn = FALSE;
    } else {
        node = NodeRemoveCasts( PTreeOp( &node ) );
        switch( node->op ) {
          case PT_INT_CONSTANT :
            pval->type = TypedefModifierRemoveOnly( node->type );
            pval->value = node->u.int64_constant;
            retn = TRUE;
            break;
          case PT_SYMBOL :
            sym = node->u.symcg.symbol;
            retn = SymIsConstantInt( sym );
            if( retn ) {
                SymConstantValue( sym, pval );
            }
            break;
          default :
            retn = FALSE;
            break;
        }
    }
    return retn;
}


boolean NodeIsIntConstant       // TEST IF INTEGRAL CONSTANT AND GET VALUE
    ( PTREE node                // - potential constant node
    , INT_CONSTANT* pval )      // - addr[ value ]
{
    boolean retn;               // - return: TRUE ==> is integral constant

    if( NULL == IntegralType( node->type ) ) {
        retn = FALSE;
    } else {
        retn = nodeGetConstant( node, pval );
    }
    return retn;
}


boolean NodeIsZeroConstant(     // TEST IF A ZERO INTEGER CONSTANT
    PTREE node )                // - node
{
    boolean retn;               // - TRUE ==> is zero constant
    INT_CONSTANT icon;          // - integral constant

    if( nodeGetConstant( node, &icon ) ) {
        retn = ( 0 == icon.value.u._32[0] && 0 == icon.value.u._32[1] );
    } else {
        retn = FALSE;
    }
    return retn;
}


PTREE NodeFromConstSym(         // BUILD CONSTANT NODE FROM CONSTANT SYMBOL
    SYMBOL con )                // - constant symbol
{
    INT_CONSTANT icon;          // - integral constant
    PTREE retn;                 // - new entry

    con = SymConstantValue( con, &icon );
    retn = PTreeInt64Constant( icon.value, TYP_SLONG64 );
    retn->type = SymUnmodifiedType( con );
    return retn;
}


void NodeFreeSearchResult(      // FREE SEARCH_RESULT FROM A NODE
    PTREE node )                // - the node
{
    if( node->op == PT_SYMBOL ) {
        ScopeFreeResult( node->u.symcg.result );
        node->u.symcg.result = NULL;
    }
}


static boolean nodeIsAssignment(// TEST IF NODE IS "=" or initialization
    PTREE node )                // - node
{
    return NodeIsBinaryOp( node, CO_EQUAL )
        || NodeIsBinaryOp( node, CO_INIT )
        || NodeIsBinaryOp( node, CO_EQUAL_REF )
        || NodeIsBinaryOp( node, CO_INIT_REF );
}


static PTREE nodeSimplifyComma( // REMOVE CO_TRASH TO GET RVALUE
    PTREE node )                // - the node
{
    PTREE trash;                // - trash node
    PTREE op;                   // - assignment operator
    PTREE dup;                  // - duplicating node
    PTREE right;                // - node to right of comma

    if( NodeIsBinaryOp( node, CO_COMMA ) ) {
        right = node->u.subtree[1];
        if( right->op == PT_SYMBOL ) {
            op = PTreeOpLeft( node );
            if( nodeIsAssignment( op ) ) {
                dup = PTreeOpLeft( op );
                if( ( dup->op == PT_SYMBOL )
                  &&( dup->u.symcg.symbol == right->u.symcg.symbol ) ) {
                    trash = node;
                    node = node->u.subtree[0];
                    trash->u.subtree[0] = NULL;
                    NodeFreeDupedExpr( trash );
                }
            }
        } else if( ( right->op == PT_DUP_EXPR )
                 &&( right->u.dup.subtree[0] == NULL ) ) {
            op = PTreeOpLeft( node );
            if( nodeIsAssignment( op ) ) {
                dup = PTreeOpLeft( op );
                if( ( dup->op == PT_DUP_EXPR )
                  &&( dup->u.dup.node == right->u.dup.node ) ) {
                    DbgUseless();
                    op->u.subtree[0] = dup->u.dup.subtree[0];
                    PTreeFree( dup );
                    trash = node;
                    node = node->u.subtree[0];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?