analnew.c

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

C
913
字号
/****************************************************************************
*
*                            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 "cgfront.h"
#include "memmgr.h"
#include "fnovload.h"
#include "calldiag.h"
#include "errdefns.h"
#include "rtfuncod.h"
#include "fold.h"
#include "defarg.h"
#include "typesig.h"
#include "fnbody.h"
#include "ctexcept.h"


static PTREE sizeOfUInt( void )
{
    return NodeOffset( SizeTargetSizeT() );
}

static PTREE newCheckForNULL( PTREE value, PTREE t_expr )
{
    PTREE b_expr;
    PTREE f_expr;

    f_expr = value;
    value = NodeDupExpr( &f_expr );
    b_expr = NodeCompareToZero( value );
    return( NodeTestExpr( b_expr, t_expr, f_expr ) );
}

static TYPE figureOutNewType( PTREE *pnumber, TYPE *of_type )
{
    PTREE array_number;
    PTREE extra_number;
    TYPE type;
    TYPE test_type;
    TYPE base_type;
    TYPE new_expr_type;
    target_size_t number;
    target_size_t size;

    /* adjust for cases like "new T" where T is an array typedef */
    array_number = *pnumber;
    type = *of_type;
    if( array_number == NULL ) {
        test_type = ArrayType( type );
        if( test_type != NULL ) {
            array_number = NodeOffset( test_type->u.a.array_size );
            new_expr_type = PointerTypeForArray( type );
            type = test_type->of;
        } else {
            new_expr_type = MakePointerTo( type );
        }
    } else {
        new_expr_type = MakePointerTo( type );
    }
    test_type = ArrayType( type );
    if( test_type != NULL ) {
        /* the base type is an array */
        size = CgTypeSize( type );
        base_type = ArrayBaseType( type );
        number = size / CgTypeSize( base_type );
        extra_number = NodeOffset( number );
        if( array_number != NULL ) {
            array_number = NodeRvalue( array_number );
            array_number = NodeBinary( CO_TIMES, array_number, extra_number );
            array_number->type = extra_number->type;
            array_number = FoldBinary( array_number );
        } else {
            array_number = extra_number;
        }
        type = base_type;
    }
    *of_type = type;
    *pnumber = array_number;
    return( new_expr_type );
}

static SEARCH_RESULT *findNewDelOp( SCOPE search_scope, char *name )
{
    SEARCH_RESULT *result;

    result = NULL;
    if( ! ScopeType( search_scope, SCOPE_FILE ) ) {
        result = ScopeFindMember( search_scope, name );
    }
    // if not found in class scope; search file scope
    if( result == NULL ) {
        result = ScopeFindNaked( GetFileScope(), name );
    }
    return( result );
}

static SYMBOL accessDelete(     // ACCESS DELETE OPERATOR SYMBOL
    unsigned delete_op,         // - CO_DELETE or CO_DELETE_ARRAY
    SCOPE scope,                // - scope to search
    unsigned *num_args,         // - fill in # of arguments
    SEARCH_RESULT **presult )   // - fill in SEARCH_RESULT (if req'd)
{
    SEARCH_RESULT *result;
    SYMBOL del_sym;
    arg_list *args;

    /* there is always an "operator delete" */
    result = findNewDelOp( scope, CppOperatorName( delete_op ) );
    /* remember that delete cannot be overloaded */
    del_sym = result->sym_name->name_syms;
    if( presult == NULL ) {
        ScopeFreeResult( result );
    } else {
        *presult = result;
    }
    args = SymFuncArgList( del_sym );
    *num_args = args->num_args;
    return del_sym;
}


static SYMBOL checkDeleteResult( // CHECK ACCESS FOR DELETE SEARCH_RESULT
    SYMBOL sym,                 // - delete operator
    SEARCH_RESULT* result,      // - search result
    TOKEN_LOCN *locn,           // - error location
    boolean compiling_dtor )    // - TRUE ==> compiling delete inside DTOR
{
    if( result != NULL ) {
        ScopeResultErrLocn( result, locn );
        if( ( ! compiling_dtor ) && ScopeCheckSymbol( result, sym ) ) {
            sym = NULL;
        }
        ScopeFreeResult( result );
    }
    return sym;
}


static SYMBOL checkDeleteAccess( // CHECK ACCESS OF DELETE OPERATOR
    unsigned delete_op,         // - CO_DELETE or CO_DELETE_ARRAY
    SCOPE scope,                // - scope for operator
    unsigned *num_args,         // - number of arguments
    TOKEN_LOCN *locn,           // - error location
    boolean compiling_dtor )    // - TRUE ==> compiling delete inside DTOR
{
    SYMBOL sym;                 // - delete operator
    SEARCH_RESULT *result;      // - search result

    sym = accessDelete( delete_op, scope, num_args, &result );
    sym = checkDeleteResult( sym, result, locn, compiling_dtor );
    return sym;
}


static PTREE setupArrayStorage( // STORE COUNT IN ARRAY_STORAGE,POINT TO ARRAY
    PTREE expr,                 // - ARRAY_STORAGE pointer expression
    TYPE new_expr_type,         // - TYPE of expression
    PTREE array_number )        // - expression for count
{
    expr = NodeConvertFlags( GetBasicType( TYP_UINT ), expr, PTF_LVALUE );
    expr = NodeAssign( expr, array_number );
    expr = NodeConvert( new_expr_type, expr );
    expr = NodeBinary( CO_PLUS, expr, sizeOfUInt() );
    expr->type = new_expr_type;
    return expr;
}


static unsigned checkNewCtor(   // CHECK CTOR'ING OK FOR NEW
    TYPE class_type,            // - NULL or class type
    TYPE base_type,             // - base type of type being new'ed
    SYMBOL* a_ctor,             // - addr[ ctor symbol ]
    PTREE* a_initial,           // - addr[ initialization parse tree ]
    TOKEN_LOCN* err_locn )      // - error location
{
    unsigned ctor_overload;     // - analysis result
    PTREE initial;              // - initialization parse tree
    FNOV_DIAG fnov_diag;

    ctor_overload = AnalyseCtorDiag( base_type
                                   , a_ctor
                                   , a_initial
                                   , &fnov_diag );
    initial = *a_initial;
    switch( ctor_overload ) {
      case CNV_ERR :
      case CNV_OK :
        break;
      case CNV_AMBIGUOUS :
        CallDiagAmbiguous( initial, ERR_CTOR_AMBIGUOUS, &fnov_diag );
        break;
      case CNV_IMPOSSIBLE :
        if( initial == NULL ) {
            if( class_type != NULL ) {
                if( ! TypeNeedsCtor( class_type ) ) {
                    /* no initializer and struct type */
                    /* but struct doesn't need a ctor */
                    ctor_overload = CNV_OK;
                    break;
                }
            } else {
                /* no initializer and non-struct type */
                ctor_overload = CNV_OK;
                break;
            }
            SetErrLoc( err_locn );
            CErr1( ERR_NO_CTOR_FOR_NEW );
        } else {
            ConversionTypesSet( NodeType( initial ), base_type );
            initial = NodeBinary( CO_CTOR, NULL, initial );
            *a_initial = initial;
            initial = PTreeCopySrcLocation( initial, initial->u.subtree[1] );
            CtorDiagNoMatch( initial, ERR_NO_CTOR_FOR_NEW, &fnov_diag );
            ConversionDiagnoseInf();
        }
        break;
      default :
        if( initial == NULL ) {
            SetErrLoc( err_locn );
            CErr1( ERR_NO_CTOR_FOR_NEW );
        } else {
            ConversionTypesSet( NodeType( initial ), base_type );
            PTreeErrorExpr( initial, ERR_NO_CTOR_FOR_NEW );
            ConversionDiagnoseInf();
        }
    }
    FnovFreeDiag( &fnov_diag );
    return ctor_overload;
}

static SCOPE scopeLookup( TYPE type )
{
    SCOPE scope;

    type = StructType( type );
    if( type == NULL ) {
        scope = GetFileScope();
    } else {
        scope = type->u.c.scope;
    }
    return scope;
}

static SCOPE opNewSearchScope( TYPE new_type, CGOP cgop )
{
    SCOPE scope;

    scope = GetFileScope();
    if( cgop != CO_NEW_G ) {
        scope = scopeLookup( new_type );
    }
    return( scope );
}

static PTREE buildNewCall(      // BUILD CALL TO NEW OPERATOR
    PTREE node,                 // - arguments
    SCOPE opnew_scope,          // - scope to search for op new
    TYPE new_expr_type,         // - type of new'ed expression
    unsigned count_placement,   // - # arguments
    TOKEN_LOCN* err_locn,       // - error location
    unsigned operator_code )    // - operator code
{
    arg_list *alist;            // - arguments structure
    PTREE *ptlist;              // - parse tree for arguments
    SEARCH_RESULT *result_new;  // - search result for operator new
    SYMBOL sym;                 // - symbol for operator new
    FNOV_RESULT ovret;          // - overload resolution result
    char *name;                 // - op new name
    TEMP_PT_LIST default_list;  // - default PTREE list
    TEMP_ARG_LIST default_args; // - default arg_list
    FNOV_DIAG fnov_diag;        // - diagnosis information

    name = CppOperatorName( operator_code );
    result_new = findNewDelOp( opnew_scope, name );
    ScopeResultErrLocn( result_new, err_locn );
    /* will always find an "operator new" or "operator new[] */

⌨️ 快捷键说明

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