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 + -
显示快捷键?