analctor.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 676 行 · 第 1/2 页
C
676 行
// list
// - the ctor SYMBOL is found
//
// - the initializer list is converted to a parse tree which can be used
// by EffectCtor
//
// - an error can be detected by examining the returned initializer list to
// see if it starts with a PT_ERROR node
//
static CNV_RETN analyseTypeCtorDiag( // ANALYSE CONSTRUCTOR FOR A TYPE
SCOPE scope, // - start scope for component ctors (NULLable)
TYPE type, // - type for CTOR
unsigned conversion, // - type of conversion reqd
SYMBOL *ctor, // - ctor to be filled in
PTREE *initial, // - initialization arguments (modified)
FNOV_DIAG *fnov_diag ) // - diagnosis information
{
PTREE expr; // - original args
TYPE base_type; // - base type
CNV_RETN retn; // - return: CNV_...
*ctor = NULL;
expr = *initial;
base_type = TypedefModifierRemoveOnly( type );
switch( base_type->id ) {
default :
retn = CNV_IMPOSSIBLE;
break;
case TYP_ERROR:
/* we've already diagnosed something somewhere */
retn = CNV_ERR;
break;
case TYP_BITFIELD :
return analyseTypeCtorDiag( scope
, base_type->of
, conversion
, ctor
, initial
, fnov_diag );
break;
case TYP_FUNCTION :
case TYP_VOID :
if( NULL == *initial ) {
retn = CNV_IMPOSSIBLE;
break;
}
// drops thru
case TYP_BOOL :
case TYP_CHAR :
case TYP_SCHAR :
case TYP_UCHAR :
case TYP_WCHAR :
case TYP_SSHORT :
case TYP_USHORT :
case TYP_SINT :
case TYP_UINT :
case TYP_SLONG :
case TYP_ULONG :
case TYP_SLONG64 :
case TYP_ULONG64 :
case TYP_FLOAT :
case TYP_DOUBLE :
case TYP_LONG_DOUBLE :
case TYP_ENUM :
case TYP_POINTER :
case TYP_MEMBER_POINTER :
retn = single_arg( initial );
if( retn == CNV_ERR ) break;
if( *initial == NULL ) break;
*initial = CastImplicit( *initial, base_type, CNV_INIT, &diagCtor );
if( PT_ERROR == (*initial)->op ) {
retn = CNV_ERR;
} else {
retn = CNV_OK;
}
break;
case TYP_CLASS :
retn = analyseCtorClassDiag( base_type, scope, ctor, expr, initial, fnov_diag );
break;
case TYP_ARRAY :
if( expr != NULL ) {
PTreeErrorExpr( expr, ERR_CANT_INIT_NEW_ARRAY );
retn = CNV_IMPOSSIBLE;
} else {
retn = AnalyseCtorDiag( ArrayBaseType( type ), ctor, initial, NULL );
}
break;
}
return retn;
}
CNV_RETN AnalyseTypeCtor( // ANALYSE CONSTRUCTOR FOR A TYPE
SCOPE scope, // - start scope for component ctors (NULLable)
TYPE type, // - type for CTOR
unsigned conversion, // - type of conversion reqd
SYMBOL *ctor, // - ctor to be filled in
PTREE *initial ) // - initialization arguments (modified)
{
return analyseTypeCtorDiag( scope
, type
, conversion
, ctor
, initial
, NULL );
}
CNV_RETN AnalyseCtorDiag( // ANALYSE CONSTRUCTOR
TYPE type, // - type for CTOR
SYMBOL *ctor, // - ctor to be filled in
PTREE *initial, // - initialization arguments (modified)
FNOV_DIAG *fnov_diag ) // Don't know how to implement LMW
{
TYPE class_type;
PTREE expr;
class_type = StructType( type );
fnov_diag = FnovInitDiag( fnov_diag );
if( class_type != NULL ) {
*ctor = NULL;
expr = *initial;
if( ! TypeDefedNonAbstract( class_type
, expr
, ERR_CONSTRUCT_AN_ABSTRACT_TYPE
, ERR_CONSTRUCT_AN_UNDEFD_TYPE ) ) {
return( CNV_ERR );
}
}
return analyseTypeCtorDiag( NULL
, type
, CNV_CAST
, ctor
, initial
, fnov_diag );
}
static PTREE bareArg( // STRIP LIST NODE FROM ARGUMENT
PTREE arg ) // - CO_LIST node
{
PTREE retn; // - target node
DbgVerify( NodeIsBinaryOp( arg, CO_LIST ), "bareArg -- impossible" );
retn = arg->u.subtree[1];
PTreeFree( arg );
return retn;
}
PTREE EffectCtor( // EFFECT A CONSTRUCTION
PTREE initial, // - initialization list
SYMBOL ctor, // - constructor
TYPE base_type, // - type being constructed
PTREE this_node, // - NULL, or node for "this"
TOKEN_LOCN *err_locn, // - error location
unsigned control ) // - control mask
{
PTREE node; // - resultant node
CNV_RETN retn; // - conversion return
/*
if the caller depends on a non-NULL 'this_node' being the final
value of the expression returned by EffectCtor, see the code in
AnalyseNew()
*/
switch( base_type->id ) {
case TYP_BOOL :
case TYP_CHAR :
case TYP_SCHAR :
case TYP_UCHAR :
case TYP_WCHAR :
case TYP_SSHORT :
case TYP_USHORT :
case TYP_SINT :
case TYP_UINT :
case TYP_SLONG :
case TYP_ULONG :
case TYP_SLONG64 :
case TYP_ULONG64 :
case TYP_FLOAT :
case TYP_DOUBLE :
case TYP_LONG_DOUBLE :
case TYP_ENUM :
case TYP_BITFIELD :
case TYP_FUNCTION :
case TYP_POINTER :
case TYP_MEMBER_POINTER :
if( initial == NULL ) {
initial = NodeZero();
}
if( this_node == NULL ) {
node = NodeConvert( base_type, initial );
} else {
if( base_type->id == TYP_MEMBER_POINTER ) {
node = NodeBinary( CO_INIT, this_node, initial );
node->type = this_node->type;
retn = MembPtrAssign( &node );
/* value of expression is 'this_node' */
ConversionDiagnose( retn, node, &diagCtor );
} else {
PTREE dup;
dup = NULL;
if( control & EFFECT_VALUE_THIS ) {
dup = NodeDupExpr( &this_node );
}
if( base_type->id == TYP_BITFIELD ) {
this_node = NodeUnaryCopy( CO_BITFLD_CONVERT, this_node );
this_node->type = base_type->of;
}
node = NodeBinary( NULL == TypeReference( base_type )
? CO_INIT : CO_INIT_REF
, this_node
, initial );
node->type = this_node->type;
if( dup != NULL ) {
node = NodeComma( node, dup );
}
}
}
break;
case TYP_CLASS :
if( ctor == NULL ) {
node = ClassDefaultCopy( this_node, bareArg( initial ) );
} else {
boolean check_dtoring; // - TRUE ==> need to check DTORing
TYPE this_type; // - type of this arg
CALL_OPT opt; // - type of optimization
PTREE bare; // - bare source operand
PTREE co_dtor; // - CO_DTOR operand
if( this_node == NULL ) {
this_node = NodeTemporary( base_type );
this_node = PTreeSetLocn( this_node, err_locn );
check_dtoring = TRUE;
} else {
check_dtoring = FALSE;
}
if( initial != NULL
&& initial->u.subtree[0] == NULL
&& base_type == ClassTypeForType( initial->type ) ) {
opt = AnalyseCallOpts( base_type
, initial->u.subtree[1]
, &co_dtor
, &bare );
if( opt != CALL_OPT_NONE ) {
initial = bareArg( initial );
}
} else {
opt = CALL_OPT_NONE;
}
if( opt == CALL_OPT_NONE ) {
arg_list *args; // - function arguments
if( control & EFFECT_EXACT ) {
this_node->flags |= PTF_MEMORY_EXACT;
}
args = SymFuncArgList( ctor );
this_type = base_type;
if( args->qualifier != 0 ) {
this_type = MakeModifiedType( this_type
, args->qualifier );
}
if( NULL == PointerTypeEquivalent( this_node->type ) ) {
this_type = MakeReferenceTo( this_type );
} else {
this_type = MakePointerTo( this_type );
}
this_node = CastImplicit( this_node
, this_type
, CNV_FUNC_CD_THIS
, &diagCtor );
if( PT_ERROR == this_node ) {
NodeFreeDupedExpr( initial );
node = PTreeErrorNode( this_node );
break;
}
node = NodeMakeCall( ctor
, SymFuncReturnType( ctor )
, initial );
node->flags |= PTF_LVALUE;
node = PTreeSetLocn( node, err_locn );
if( AddDefaultArgs( ctor, node ) ) {
node = CallArgsArrange( ctor->sym_type
, node
, node->u.subtree[1]
, NodeArg( this_node )
, CallArgumentExactCtor
( base_type
, ( control & EFFECT_EXACT ) != 0 )
, NULL );
}
} else {
node = CopyOptimize( bare
, initial
, this_node
, co_dtor
, opt );
control &= ~ EFFECT_CTOR_DECOR;
}
if( node->op == PT_ERROR ) break;
if( check_dtoring ) {
node = NodeDtorExpr( node, this_node->u.symcg.symbol );
if( node->op == PT_ERROR ) break;
}
if( control & EFFECT_EXACT ) {
node->flags |= PTF_MEMORY_EXACT;
}
if( control & EFFECT_CTOR_DECOR ) {
if( control & EFFECT_DECOR_COMP ) {
unsigned kind;
node = PtdScopeCall( node, ctor );
if( control & EFFECT_EXACT ) {
kind = DTC_COMP_MEMB;
} else if( control & EFFECT_VIRTUAL ) {
kind = DTC_COMP_VBASE;
} else {
kind = DTC_COMP_DBASE;
}
node = PtdDtorKind( node, kind );
node = PtdCtoredComponent( node, base_type );
} else if( control & EFFECT_DECOR_TEMP ) {
node = PtdCtoredExprType( node, ctor, base_type );
} else {
node = PtdCtoredScopeType( node, ctor, base_type );
}
}
}
break;
case TYP_VOID :
node = NodeUnary( CO_TRASH_EXPR, node );
node->type = base_type;
break;
default :
node = this_node;
break;
}
return node;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?