analconv.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 372 行
C
372 行
/****************************************************************************
*
* 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 "fnovload.h"
#include "errdefns.h"
#include "cgsegid.h"
#include "defarg.h"
#include "class.h"
#include "objmodel.h"
#include "ptrcnv.h"
#include "stats.h"
#include "initdefs.h"
static unsigned get_ptr_cv( // GET CONST/VOLATILE POINTED AT
TYPE type ) // - type
{
TYPE ptype; // - pointer base type
TYPE mtype; // - member pointer base type
type_flag flags; // - modifier flags
ptype = PointerTypeEquivalent( type );
if( ptype != NULL ) {
TypeModFlagsEC( ptype->of, &flags );
flags &= TF1_CV_MASK;
} else {
mtype = MemberPtrType( type );
if( mtype != NULL ) {
TypeModFlagsEC( mtype->of, &flags );
flags &= TF1_CV_MASK;
} else {
flags = 0;
}
}
return flags;
}
unsigned AnalysePtrCV( // CHECK PTR CONVERSION FOR CONST/VOLATILE
PTREE expr, // - expression for error
TYPE proto, // - type of target
TYPE argument, // - type of source
unsigned conversion ) // - type of conversion
{
unsigned retn; // - return: CNV_...
unsigned cv_proto; // - const/volatile for prototype
unsigned cv_argument; // - const/volatile for argument
TYPE refed; // - a reference type
refed = TypeReference( proto );
if( refed == NULL ) {
refed = TypeReference( argument );
if( refed != NULL ) {
argument = refed;
}
}
cv_proto = get_ptr_cv( proto );
cv_argument = get_ptr_cv( argument );
if( TF1_CONST & cv_argument & ~ cv_proto ) {
switch( conversion ) {
case CNV_INIT :
case CNV_INIT_COPY :
if( NULL == TypeReference( proto ) ) {
PTreeErrorExpr( expr, ERR_CONST_PTR_INIT );
} else {
PTreeErrorExpr( expr, ERR_CONST_REF_INIT );
}
retn = CNV_ERR;
break;
case CNV_FUNC_DARG :
case CNV_FUNC_ARG :
PTreeErrorExpr( expr, ERR_CONST_PTR_ARG );
retn = CNV_ERR;
break;
case CNV_FUNC_THIS :
PTreeErrorExpr( expr, ERR_CONST_PTR_THIS );
retn = CNV_ERR;
break;
case CNV_FUNC_RET :
PTreeErrorExpr( expr, ERR_CONST_PTR_RETURN );
retn = CNV_ERR;
break;
default :
retn = CNV_OK;
break;
}
} else {
retn = CNV_OK;
}
if( ( retn == CNV_OK )
&&( TF1_VOLATILE & cv_argument & ~ cv_proto ) ) {
switch( conversion ) {
case CNV_INIT :
case CNV_INIT_COPY :
PTreeErrorExpr( expr, ERR_VOLATILE_PTR_INIT );
retn = CNV_ERR;
break;
case CNV_FUNC_DARG :
case CNV_FUNC_ARG :
PTreeErrorExpr( expr, ERR_VOLATILE_PTR_ARG );
retn = CNV_ERR;
break;
case CNV_FUNC_THIS :
PTreeErrorExpr( expr, ERR_VOLATILE_PTR_THIS );
retn = CNV_ERR;
break;
case CNV_FUNC_RET :
PTreeErrorExpr( expr, ERR_VOLATILE_PTR_RETURN );
retn = CNV_ERR;
break;
default :
retn = CNV_OK;
break;
}
}
return( retn );
}
#ifdef XTRA_RPT
ExtraRptTable( cnvKind, 20, 1 ); // counts converted cases
ExtraRptTable( cnvType, 13, 1 ); // counts "conversion"
static void init( // START OF RANK REPORTING
INITFINI* defn ) // - definition
{
defn = defn;
ExtraRptRegisterTab( "Conversion Kinds"
, NULL
, cnvKind
, sizeof( cnvKind ) / sizeof( cnvKind[0] )
, 1);
ExtraRptRegisterTab( "Conversion Types"
, NULL
, cnvType
, sizeof( cnvType ) / sizeof( cnvType[0] )
, 1);
}
INITDEFN( cnv_reports, init, InitFiniStub );
#endif
unsigned ConvertOvFunNode( // CONVERT FUN (FUN IS OVERLOADED), NO FREE
TYPE tgt, // - target type
PTREE func ) // - overloaded function
{
unsigned retn; // - conversion return
SEARCH_RESULT *result; // - previous search result
SYMBOL sym; // - symbol for function
TYPE points; // - unmodified pointer to function
FNOV_RESULT ov_retn; // - return from overloading
points = PointerTypeEquivalent( tgt );
if( points == NULL ) {
retn = CNV_IMPOSSIBLE;
} else {
points = FunctionDeclarationType( points->of );
if( points == NULL ) {
retn = CNV_IMPOSSIBLE;
} else {
sym = func->u.symcg.symbol;
if( SymIsUDC( sym ) ) {
ov_retn = UdcOverloaded( &sym
, func->u.symcg.result
, sym
, points->of
, points->u.f.args->qualifier );
} else {
ov_retn = FuncOverloadedLimitDiag( &sym
, func->u.symcg.result
, sym
, points->u.f.args
, NULL
, FNC_EXCLUDE_DEFARG
, NULL );
}
switch( ov_retn ) {
case FNOV_AMBIGUOUS :
retn = CNV_IMPOSSIBLE;
break;
case FNOV_NO_MATCH :
retn = CNV_IMPOSSIBLE;
break;
case FNOV_NONAMBIGUOUS :
result = func->u.symcg.result;
if( ScopeCheckSymbol( result, sym ) ) {
retn = CNV_ERR;
} else {
DbgAssert( sym->id != SC_DEFAULT );
if( sym->id == SC_DEFAULT ) {
retn = CNV_IMPOSSIBLE;
} else {
func->u.symcg.symbol = sym;
func->type = sym->sym_type;
retn = CNV_OK;
}
}
break;
DbgDefault( "ConvertOvFunNode: unexpected return" );
}
}
}
return( retn );
}
static unsigned diagnoseCommon( // DIAGNOSE A COMMON CONVERSION
CTD ctd, // - derivation type
CNV_DIAG *diagnosis, // - diagnosis
PTREE expr ) // - common expression
{
unsigned retn; // - conversion return: CNV_...
TYPE left; // - type of operand on left
TYPE right; // - type of operand on right
switch( ctd ) {
case CTD_RIGHT :
case CTD_RIGHT_VIRTUAL :
case CTD_NO :
case CTD_LEFT :
case CTD_LEFT_VIRTUAL :
retn = CNV_IMPOSSIBLE;
break;
case CTD_LEFT_AMBIGUOUS :
case CTD_RIGHT_AMBIGUOUS :
retn = CNV_AMBIGUOUS;
break;
case CTD_LEFT_PRIVATE :
case CTD_RIGHT_PRIVATE :
retn = CNV_PRIVATE;
break;
case CTD_LEFT_PROTECTED :
case CTD_RIGHT_PROTECTED :
retn = CNV_PROTECTED;
break;
}
left = NodeType( expr->u.subtree[0] );
right = NodeType( expr->u.subtree[1] );
ConversionInfDisable();
ConversionDiagnose( retn, expr, diagnosis );
ConversionDiagLR( left, right );
return CNV_ERR;
}
static boolean convertCommonClass(// CONVERT TO COMMON TYPE, FROM CLASS
PTREE *a_expr, // - binary expression
CNV_DIAG *diagnosis ) // - used to diagnose errors
{
boolean cretn; // - TRUE ==> conversion handled
PTREE expr; // - expression
PTREE* a_cnv; // - converted subtree
PTREE cnv; // - converted subtree
CTD ctd; // - common-type derivation
TYPE tgt_type; // - target type
expr = *a_expr;
ctd = TypeCommonDerivation( expr->u.subtree[0]->type
, expr->u.subtree[1]->type );
switch( ctd ) {
case CTD_NO :
if( CastCommonClass( a_expr, diagnosis ) ) {
return TRUE;
}
// drops thru
case CTD_LEFT_AMBIGUOUS :
case CTD_LEFT_PRIVATE :
case CTD_LEFT_PROTECTED :
case CTD_RIGHT_AMBIGUOUS :
case CTD_RIGHT_PRIVATE :
case CTD_RIGHT_PROTECTED :
diagnoseCommon( ctd, diagnosis, expr );
break;
case CTD_LEFT :
case CTD_LEFT_VIRTUAL :
a_cnv = &expr->u.subtree[0];
tgt_type = expr->u.subtree[1]->type;
break;
case CTD_RIGHT :
case CTD_RIGHT_VIRTUAL :
a_cnv = &expr->u.subtree[1];
tgt_type = expr->u.subtree[0]->type;
break;
}
if( PT_ERROR == expr->op ) {
cretn = FALSE;
} else {
cnv = CastImplicit( *a_cnv, tgt_type, CNV_EXPR, diagnosis );
*a_cnv = cnv;
if( PT_ERROR == cnv->op ) {
PTreeErrorNode( expr );
cretn = FALSE;
} else {
expr = NodeSetType( expr, cnv->type, PTF_LV_CHECKED );
cretn = TRUE;
}
}
*a_expr = expr;
return cretn;
}
static boolean nodeMemberPtr( // TEST IF NODE IS MEMB-PTR
PTREE node ) // - NODE
{
return NULL != MemberPtrType( TypeReferenced( node->type ) );
}
boolean ConvertCommonType( // CONVERT TO COMMON TYPE (:, ==, !=)
PTREE *a_expr, // - addr [ expression ]
CNV_DIAG *diag_class, // - diagnosis: class
CNV_DIAG *diag_mem_ptr ) // - diagnosis: member ptr.
{
boolean retn; // - FALSE ==> diagnose bad operands
PTREE expr; // - expression
expr = *a_expr;
if( NULL != StructType( expr->u.subtree[0]->type )
|| NULL != StructType( expr->u.subtree[1]->type ) ) {
retn = convertCommonClass( a_expr, diag_class );
} else
if( nodeMemberPtr( expr->u.subtree[0] )
|| nodeMemberPtr( expr->u.subtree[1] ) ) {
expr->u.subtree[0] = NodeRvalueLeft( expr );
expr->u.subtree[1] = NodeRvalueRight( expr );
expr = MembPtrCommonType( expr );
*a_expr = expr;
if( PT_ERROR == expr->op ) {
ConversionDiagnose( CNV_ERR, expr, diag_mem_ptr );
}
retn = TRUE;
} else {
retn = FALSE;
}
return retn;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?