anallval.c

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

C
1,061
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"
#include "memmgr.h"
#include "cgfront.h"
#include "fold.h"
#include "errdefns.h"
#include "objmodel.h"
#include "stats.h"
#include "brinfo.h"


#define isUDF( node ) ( node->cgop == CO_NAME_CONVERT )


static TYPE lvalueErrMsg(       // GENERATE NOT-LVALUE ERROR MESSAGE
    PTREE expr_chk,             // - expression, to be checked
    PTREE expr_err,             // - expression, for error
    unsigned msg_normal,        // - msg, when normal
    unsigned msg_cast )         // - msg, when cast
{
    if( NodeIsBinaryOp( expr_chk, CO_CONVERT ) ) {
        expr_chk = PTreeOpLeft( expr_chk );
        if( expr_chk->cgop == CO_USER_CAST ) {
            PTreeErrorExpr( expr_err, msg_cast );
        } else {
            PTreeErrorExpr( expr_err, msg_normal );
        }
    } else {
        PTreeErrorExpr( expr_err, msg_normal );
    }
    return NULL;
}


TYPE LvalueErr(                 // NOT-LVALUE ERROR (NODE)
    PTREE expr_chk,             // - expression, to be checked
    PTREE expr )                // - expression
{
    return lvalueErrMsg( expr_chk
                       , expr
                       , ERR_MUST_BE_LVALUE
                       , ERR_MUST_BE_LVALUE_CAST );
}


TYPE LvalueErrLeft(             // NOT-LVALUE ERROR (LEFT NODE)
    PTREE expr_chk,             // - expression, to be checked
    PTREE expr )                // - expression
{
    return lvalueErrMsg( expr_chk
                       , expr
                       , ERR_LEFT_MUST_BE_LVALUE
                       , ERR_LEFT_MUST_BE_LVALUE_CAST );
}


static boolean requiresThis(    // TEST IF SYMBOL REQUIRES A THIS
    SYMBOL sym )                // - symbol
{
    boolean retn;               // - TRUE ==> requires "this"
    SCOPE func_class_scope;     // - scope for function

    if( SymIsClassMember( sym ) ) {
        if( SymIsStaticMember( sym ) || SymIsEnumeration( sym ) ) {
            retn = FALSE;
        } else if( NULL == TypeThisExists() ) {
            retn = TRUE;
        } else {
            func_class_scope = ScopeFunctionScopeInProgress()->enclosing;
            if( ( func_class_scope->id == SCOPE_CLASS )
              &&( ScopeDerived( func_class_scope, SymScope( sym ) ) ) ) {
                retn = FALSE;
            } else {
                retn = TRUE;
            }
        }
    } else {
        retn = FALSE;
    }
    return retn;
}


boolean AnalyseSymbolAccess(    // ANALYSE ACCESS TO SYMBOL
    PTREE expr,                 // - expression for errors
    PTREE symbol,               // - symbol being accessed
    PTREE this_expr,            // - expression for "this"
    SYMBOL_DIAG *diag )         // - diagnosis to be used
{
    boolean retn;               // - return: TRUE ==> access ok
    SEARCH_RESULT *result;      // - search result
    TOKEN_LOCN err_locn;        // - location for errors

    PTreeExtractLocn( expr, &err_locn );
    result = symbol->u.symcg.result;
#ifdef OPT_BR
    if( CompFlags.optbr_f
     || CompFlags.optbr_m
     || CompFlags.optbr_t
     || CompFlags.optbr_v ) {
        BrinfReferenceSymbol( &err_locn, symbol->u.symcg.symbol );
    }
#endif
    ScopeResultErrLocn( result, &err_locn );
    SymSetNvReferenced( symbol->u.symcg.symbol );
    if( ScopeCheckSymbol( result, symbol->u.symcg.symbol ) ) {
        PTreeErrorNode( expr );
        retn = FALSE;
    } else if( this_expr == NULL ) {
        if( result->simple ) {
            retn = TRUE;
        } else if( result->no_this ) {
            retn = TRUE;
        } else if( requiresThis( symbol->u.symcg.symbol ) ) {
            PTreeErrorExpr( expr, diag->msg_no_this );
            retn = FALSE;
        } else {
            retn = TRUE;
        }
    } else {
        retn = SymIsClassMember( symbol->u.symcg.symbol );
    }
    return retn;
}


static SYMBOL_DIAG diagMemb =   // diagnosis for member
{   ERR_INVALID_NONSTATIC_ACCESS// - no "this"
,   ERR_EXTRA_THIS_FOR_DATA     // - extra "this" for data element
,   ERR_ENCLOSING_THIS_DATA     // - accessing enclosing class member
};


boolean AnalyseThisDataItem(    // ANALYSE "THIS" DATA ITEM IN PARSE TREE
    PTREE *a_expr )             // - addr[ expression ]
{
    boolean retn;               // - return: TRUE ==> ok
    PTREE expr;                 // - expression
    SEARCH_RESULT *result;      // - search result for node
    PTREE *r_right;             // - ref[ node for symbol to be adjusted ]
    PTREE right;                // - node for symbol to be adjusted
    unsigned offset;            // - offset for field
    TYPE type;                  // - field type
    type_flag flags;            // - cv flags, when bit field

    expr = *a_expr;
    r_right = PTreeRefRight( expr );
    right = *r_right;
    if( AnalyseSymbolAccess( expr
                           , right
                           , expr->u.subtree[0]
                           , &diagMemb ) ) {
        type = NodeType( expr->u.subtree[0] );
        type = TypedefModifierRemove( type )->of;
        type = TypeMergeForMember( type, expr->type );
        result = right->u.symcg.result;
        right->u.symcg.result = NULL;
        if( expr->u.subtree[0]->flags & PTF_MEMORY_EXACT ) {
            offset = result->exact_delta + result->offset;
            right = NodeReplace( right, NodeOffset( offset ) );
            *r_right = right;
        } else if( result->non_virtual ) {
            offset = result->delta + result->offset;
            right = NodeReplace( right, NodeOffset( offset ) );
            *r_right = right;
        } else {
            expr = NodePruneRight( expr );
            expr = NodePruneTop( expr );
            expr->flags |= PTF_PTR_NONZERO;
            NodeConvertToBasePtr( &expr, type, result, TRUE );
            expr->flags |= PTF_LVALUE | PTF_LV_CHECKED;
            expr = NodeBinary( CO_DOT, expr, NodeOffset( result->offset ) );
        }
        expr->type = type;
        expr->flags |= PTF_LVALUE;
        ScopeFreeResult( result );
        type = TypeModFlags( type, &flags );
        if( type->id == TYP_BITFIELD ) {
            expr = NodeUnaryCopy( CO_BITFLD_CONVERT, expr );
            expr->type = MakeModifiedType( type->of, flags & TF1_CV_MASK );
            expr->flags |= PTF_LVALUE;
        }
        expr = NodeSetMemoryExact( expr );
        expr = NodeFetchReference( expr );
        expr->flags |= PTF_LV_CHECKED;
        *a_expr = expr;
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return retn;
}


static PTREE reduceToRight(     // REDUCE EXPRESSION TO RIGHT EXPR
    PTREE *a_node )             // - addr( expression )
{
    PTREE node;                 // - expression

    node = NodePruneLeftTop( *a_node );
    *a_node = node;
    return node;
}


static PTREE thisPointsNode(    // MAKE this->node
    PTREE node )                // - original node
{
    TYPE type;                  // - node type
    PTREE left;                 // - this node to left

    left = NodeThisCopyLocation( node );
    if( left == NULL ) {
        PTreeErrorExpr( node, ERR_INVALID_NONSTATIC_ACCESS );
    } else {
        type = node->type;
        node = NodeBinary( CO_ARROW, left, node );
        node->type = type;
        node->flags |= PTF_LVALUE;
        node = PTreeCopySrcLocation( node, left );
    }
    return node;
}


static boolean checkConversionLookup( // CHECK RESULT OF CONVERSION LOOKUP
    SEARCH_RESULT *result,      // - result of lookup
    PTREE conv,                 // - node for conversion routine
    PTREE expr )                // - node being analysed
{
    boolean retn;               // - TRUE ==> ok

    if( ( result == NULL ) || ( result->sym == NULL ) ) {
        PTreeErrorExpr( conv, ERR_CONVERSION_NOT_DEFINED );
        PTreeErrorNode( expr );
        retn = FALSE;
    } else {
        ExtraRptSymUsage( result->sym );
        NodeSymbolCallee( conv, result->sym, result );
        retn = TRUE;
    }
    return retn;
}


static boolean checkIdLookup(   // CHECK RESULT OF ID LOOKUP
    SEARCH_RESULT *result,      // - result of lookup
    SCOPE scope,                // - scope for lookup
    PTREE id,                   // - node for id
    PTREE expr )                // - node being analysed
{
    boolean retn;               // - TRUE ==> ok
    SYMBOL sym;                 // - a symbol lookup up
    unsigned msg;               // - undeclared sym error message
    char *name;                 // - id name

    if( result == NULL ) {
        ScopeInsertErrorSym( scope, id );
        name = id->u.id.name;
        msg = ERR_UNDECLARED_SYM;
        if( ScopeType( scope, SCOPE_CLASS ) ) {
            if( NodeIsBinaryOp( expr, CO_DOT ) ) {
                msg = ERR_UNDECLARED_MEMBER;
            } else if( NodeIsBinaryOp( expr, CO_ARROW ) ) {
                msg = ERR_UNDECLARED_MEMBER;
            }
        }
        if( msg == ERR_UNDECLARED_SYM ) {
            PTreeErrorExprName( id, msg, name );
        } else {
            PTreeErrorExprNameType( id, msg, name, ScopeClass( scope ) );
        }
        PTreeErrorNode( expr );
        retn = FALSE;
    } else {
        sym = result->sym_name->name_syms;
        if( sym == NULL ) {
            PTreeErrorExpr( id, ERR_ILLEGAL_TYPE_USE );
            ScopeFreeResult( result );
            PTreeErrorNode( expr );
            retn = FALSE;
        } else if( SymIsAnError( sym ) ) {
            ScopeFreeResult( result );
            PTreeErrorNode( expr );
            retn = FALSE;
        } else if( NULL != FunctionDeclarationType( sym->sym_type ) ) {
            ExtraRptSymUsage( sym );
            NodeSymbolNoRef( id, sym, result );
            id->flags |= PTF_LV_CHECKED;
            retn = TRUE;
        } else {
            ExtraRptSymUsage( sym );
            NodeSymbol( id, sym, result );
            id->flags |= PTF_LV_CHECKED;
            retn = TRUE;
        }
    }
    return retn;
}


static boolean analyseFunction( // ANALYSE FUNCTION NODE
    PTREE expr,                 // - original expression
    PTREE func )                // - function node
{
    boolean retn;               // - TRUE ==> function ok

    if( ScopeImmediateCheck( func->u.symcg.result ) ) {
        PTreeErrorNode( expr );
        retn = FALSE;
    } else {
        expr->flags |= PTF_LVALUE;
        retn = TRUE;
    }
    return retn;
}


static void checkVolatileVar(   // SET SIDE EFFECT IF VOLATILE VARIABLE
    PTREE expr )                // - expression for variable
{
    type_flag flags;            // - flags for expression

⌨️ 快捷键说明

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