unsigned ThrowCnvInit( // THROW CONVERSIONS: INITIALIZE THROW_CNV_CTL *ctl, // - control area TYPE type ) // - type thrown { type_flag not_used; // - not used THROBJ thr_obj; // - type of throw object ctl->carver = CarveCreate( sizeof( THROW_CNV ), 8 ); ctl->hdr = NULL; ctl->cur = NULL; type = TypeCanonicalThr( type ); ctl->error_occurred = false; thr_obj = ThrowCategory( type ); if( thr_obj == THROBJ_REFERENCE ) { makeThrowCnvNoAcc( ctl, type, 0 ); } else { makeThrowCnv( ctl, type, 0 ); } switch( thr_obj ) { case THROBJ_VOID_STAR : case THROBJ_ANYTHING : case THROBJ_SCALAR : break; case THROBJ_PTR_SCALAR : makeCnvVoidStar( ctl ); break; case THROBJ_REFERENCE : type = TypeReference( type ); if( NULL != StructType( type ) ) { throwClassCnvs( type, ctl ); } else { type = TypePointedAt( type, ¬_used ); if( type != NULL ) { type = StructType( type ); if( type != NULL ) { throwClassPtrCnvs( type, ctl ); } makeCnvVoidStar( ctl ); } } break; case THROBJ_CLASS : case THROBJ_CLASS_VIRT : throwClassCnvs( type, ctl ); break; case THROBJ_PTR_CLASS : throwClassPtrCnvs( type, ctl ); makeCnvVoidStar( ctl ); break; case THROBJ_PTR_FUN : if( CgCodePtrSize() <= CgDataPtrSize() ) { makeCnvVoidStar( ctl ); } break; DbgDefault( "EXCEPT -- illegal throw object" ); } return RingCount( ctl->hdr ); }
CTD TypeCommonDerivation( // GET COMMON TYPE DERIVATION FOR TWO TYPES TYPE type1, // - type [1] (left) TYPE type2 ) // - type [2] (right) { CTD retn; // - return: CTD_... SCOPE scope1; // - scope for type[1] SCOPE scope2; // - scope for type[2] retn = CTD_NO; scope1 = TypeScope( StructType( type1 ) ); if( NULL != scope1 ) { scope2 = TypeScope( StructType( type2 ) ); if( scope1 == scope2 ) { retn = CTD_LEFT; } else if( NULL != scope2 ) { switch( ScopeDerived( scope1, scope2 ) ) { case DERIVED_YES : retn = CTD_LEFT; break; case DERIVED_YES_BUT_VIRTUAL : retn = CTD_LEFT_VIRTUAL; break; case DERIVED_YES_BUT_AMBIGUOUS : retn = CTD_LEFT_AMBIGUOUS; break; case DERIVED_YES_BUT_PRIVATE : retn = CTD_LEFT_PRIVATE; break; case DERIVED_YES_BUT_PROTECTED : retn = CTD_LEFT_PROTECTED; break; case DERIVED_NO : switch( ScopeDerived( scope2, scope1 ) ) { case DERIVED_YES : retn = CTD_RIGHT; break; case DERIVED_YES_BUT_VIRTUAL : retn = CTD_RIGHT_VIRTUAL; break; case DERIVED_YES_BUT_AMBIGUOUS : retn = CTD_RIGHT_AMBIGUOUS; break; case DERIVED_YES_BUT_PRIVATE : retn = CTD_RIGHT_PRIVATE; break; case DERIVED_YES_BUT_PROTECTED : retn = CTD_RIGHT_PROTECTED; break; case DERIVED_NO : retn = CTD_NO; break; } } } } return( retn ); }
static CLASSINFO* getClassInfo( // GET CLASS INFO FOR GOOD ELEMENTAL TYPE TYPE type ) // - type { CLASSINFO* info; // - information for class TYPE artype; // - NULL or array type if( type == NULL ) { info = NULL; } else { artype = ArrayType( type ); if( artype != NULL ) { type = ArrayBaseType( artype ); } type = StructType( type ); if( type == NULL ) { info = NULL; } else { info = TypeClassInfo( type ); if( info->corrupted ) { info = NULL; } } } return( info ); }
static TYPE arrayOrStructType // PUT TYPE INTO CONICAL FORM ( TYPE type ) // - the type { TYPE retn = StructType( type ); if( NULL == retn ) { retn = ArrayType( type ); } return retn; }
cg_type CgTypeSym( // COMPUTE OUTPUT TYPE FOR SYMBOL SYMBOL sym ) // - the symbol { TYPE type = sym->sym_type; if( SymIsArgument( sym ) && NULL != StructType( type ) && OMR_CLASS_REF == ObjModelArgument( type ) ) { type = MakeReferenceTo( type ); } return CgTypeOutput( type ); }
static DUMP_INFO* dumpStruct( // DUMP A STRUCTURE TYPE type, // - structure type DUMP_INFO* di, // - dump information char* title, // - title for dump ds_control control ) // - control word { CLASSINFO* info; // - class information NAME *parent; // - where parent ptr is stored control = control; type = StructType( type ); info = type->u.c.info; parent = VstkPush( &di->stack ); *parent = info->name; di = dumpTitle( di, title, NameStr( info->name ) ); if( type != di->original ) { di = bufferInit( di ); di = bufferStr( di, "embedded size: " ); di = bufferNmb( di, info->vsize ); di = bufferWrite( di ); di = dumpOffset( di ); di = dumpParentage( di ); } else { di = bufferInit( di ); di = bufferStr( di, "size: " ); di = bufferNmb( di, info->size ); di = bufferWrite( di ); } if( info->has_vbptr ) { di = dumpDataMemb( di , "[virtual" , "base pointer]" , info->vb_offset + di->offset , CgMemorySize( TypePtrToVoid() ) ); } if( info->has_vfptr ) { di = dumpDataMemb( di , "[virtual" , "functions pointer]" , info->vf_offset + di->offset , CgMemorySize( TypePtrToVoid() ) ); } ScopeWalkDataMembers( type->u.c.scope, dumpMember, di ); if( type == di->original ) { ScopeWalkVirtualBases( type->u.c.scope, dumpVirtual, di ); } ScopeWalkDirectBases( type->u.c.scope, dumpDirect, di ); VstkPop( &di->stack ); return di; }
THROBJ ThrowCategory( // GET THROW-OBJECT CATEGORY FOR A TYPE TYPE type ) // - type { TYPE cltype; // - class type or NULL THROBJ retn; // - category of object if( type == NULL ) { retn = THROBJ_ANYTHING; } else if( NULL != FunctionDeclarationType( type ) ) { retn = THROBJ_PTR_FUN; } else if( NULL != TypeReference( type ) ) { retn = THROBJ_REFERENCE; } else if( NULL != (cltype = StructType( type ) ) ) { if( cltype->u.c.info->last_vbase == 0 ) { retn = THROBJ_CLASS; } else { retn = THROBJ_CLASS_VIRT; } } else { type = PointerTypeEquivalent( type ); if( type == NULL ) { retn = THROBJ_SCALAR; } else if( StructType( type->of ) ) { retn = THROBJ_PTR_CLASS; } else { type = TypedefModifierRemove( type->of ); if( type->id == TYP_VOID ) { retn = THROBJ_VOID_STAR; } else if( type->id == TYP_FUNCTION ) { retn = THROBJ_PTR_FUN; } else { retn = THROBJ_PTR_SCALAR; } } } return retn; }
static boolean adjustForVirtualCall( // ADJUSTMENTS FOR POSSIBLE VIRTUAL CALL PTREE *this_node, // - addr[ "this" node ] PTREE *routine, // - routine to be called SEARCH_RESULT *result ) // - search result for routine { SYMBOL sym; // - symbol for call unsigned retn; // - return: TRUE ==> adjusted for virtual TYPE this_type; // - target type for "this" PTREE expr; // - transformed expression boolean exact_call; // - TRUE ==> this node is exact expr = *this_node; this_type = NodeType( expr ); this_type = StructType( this_type ); if( this_type != NULL ) { if( OMR_CLASS_VAL == ObjModelArgument( this_type ) ) { expr = NodeAssignTemporary( this_type, expr ); } else { expr = NodeConvert( MakePointerTo( expr->type ), expr ); } *this_node = expr; } sym = (*routine)->u.symcg.symbol; this_type = TypeThisForCall( expr, sym ); /* virtual calls don't have to check for NULL pointers when they convert */ expr->flags |= PTF_PTR_NONZERO; exact_call = expr->flags & PTF_MEMORY_EXACT; NodeConvertToBasePtr( this_node, this_type, result, TRUE ); sym = SymDefaultBase( sym ); if( ( SymIsVirtual( sym ) ) &&( ! ( (*routine)->flags & PTF_COLON_QUALED ) ) &&( ! exact_call ) ) { expr = AccessVirtualFnAddress( NodeDupExpr( this_node ) , result , sym ); expr->type = MakePointerTo( expr->type ); *routine = NodeReplace( *routine, expr ); retn = TRUE; } else { NodeFreeSearchResult( *routine ); retn = FALSE; } return( retn ); }
PTREE AnalyseReturnClassVal // RETURN CLASS VALUE ( PTREE expr ) // - expression for return { TYPE retn_type; // - return type TYPE retn_class; // - class for return PTREE tgt; // - target expression CNV_DIAG* diag; // - diagnosis retn_type = expr->u.subtree[0]->type; retn_class = StructType( retn_type ); DbgVerify( retn_class != NULL, "AnalyseReturnClassVal -- not class" ); if( ClassCorrupted( retn_class ) ) { PTreeErrorNode( expr ); } else if( TypeAbstract( retn_class ) ) { PTreeErrorExprType( expr, ERR_CONVERT_TO_ABSTRACT_TYPE, retn_class ); ScopeNotePureFunctions( retn_class ); } else { diag = DefargBeingCompiled() ? &diagDefarg : &diagReturn; tgt = NodeFetchReference( getReturnSym() ); expr = removeReturnNode( expr ); expr = CopyClassRetnVal( expr, tgt, retn_type, diag ); if( expr->op != PT_ERROR ) { if( NodeIsBinaryOp( expr, CO_DTOR ) ) { PTREE node = expr->u.subtree[0]; if( SymFunctionReturn() == node->u.symcg.symbol ) { PTreeFree( node ); node = expr; expr = expr->u.subtree[1]; PTreeFree( node ); } } } #if 0 // this is just so we can do some checking expr = CastImplicit( expr , retn_type , CNV_EXPR , DefargBeingCompiled() ? &diagDefarg : &diagReturn ); } #endif }
static void infMsgType( // DISPLAY INFORMATION FOR A CONVERSION TYPE MSG_NUM msg_num, // - message number TYPE type ) // - TYPE in error { TYPE cl_type; // - type, when class or ref to class InfMsgPtr( msg_num, type ); cl_type = ClassTypeForType( type ); if( cl_type != NULL && !TypeDefined( cl_type ) ) { InfMsgPtr( INF_CLASS_NOT_DEFINED, cl_type ); } else { TYPE ptr_type = PointerTypeEquivalent( type ); if( NULL != ptr_type ) { type_flag not_used; cl_type = StructType( TypePointedAt( type, ¬_used ) ); if( NULL != cl_type && !TypeDefined( cl_type ) ) { InfMsgPtr( INF_CLASS_NOT_DEFINED, cl_type ); } } } }
static void typeSigAccess( // HANDLE ACCESS FOR TYPE-SIGNATURE TYPE_SIG_ACCESS acc, // - access type TYPE_SIG *sig, // - current signature TOKEN_LOCN* err_locn, // - error location for access errors bool *error_occurred ) // - to set error indication { ACCINFO info; // - access information if( (TSA_GEN & acc) == 0 ) { info.acc = acc; info.type = StructType( sig->type ); if( info.type != NULL ) { info.err_occurred = error_occurred; info.err_locn = err_locn; info.access_scope = GetCurrScope(); info.class_scope = TypeScope( info.type ); typeSigAccessVar( TSA_DTOR, &sig->dtor, &info ); typeSigAccessVar( TSA_DEFAULT_CTOR, &sig->default_ctor, &info ); typeSigAccessVar( TSA_COPY_CTOR, &sig->copy_ctor, &info ); SetCurrScope(info.access_scope); } } }
static void pragDumpObjectModel( // DUMP OBJECT MODEL void ) { if( IS_ID_OR_KEYWORD( CurToken ) ) { NAME name = NameCreateLen( Buffer, TokenLen ); SEARCH_RESULT* result = ScopeFindNaked( GetCurrScope(), name ); if( result == NULL ) { CErr2p( ERR_DUMP_OBJ_MODEL, Buffer ); } else { SYMBOL_NAME sname = result->sym_name; ScopeFreeResult( result ); if( sname->name_syms == NULL ) { TYPE type = sname->name_type->sym_type; if( TypeDefined( type ) ) { TYPE dump_type; dump_type = StructType( type ); if( dump_type != NULL ) { DumpObjectModelClass( dump_type ); } else { dump_type = EnumType( type ); if( dump_type != NULL ) { DumpObjectModelEnum( dump_type ); } else { CErr2p( ERR_DUMP_OBJ_MODEL, Buffer ); } } } else { CErr2p( ERR_DUMP_OBJ_MODEL, Buffer ); } } else { CErr2p( ERR_DUMP_OBJ_MODEL, Buffer ); } } NextToken(); } }
bool PtrCnvInfo( // FILL IN PTR-CONVERSION INFORMATION TYPE ptr_src, // - source type TYPE ptr_tgt, // - target pointer type PTRCNV* info ) // - pointer-conversion information { bool ok; // - return: true ==> can convert trivially bool first_level; // - true ==> at first level bool const_always; // - true ==> const on all preceding levels TYPE orig_src; // - original src type info->converts = false; info->to_base = false; info->to_derived = false; info->to_void = false; info->ptr_integral_ext = false; info->cv_err_0 = false; info->reint_cast_ok = false; orig_src = ptr_src; ptr_src = TypePointedAtModified( ptr_src ); ptr_tgt = TypePointedAtModified( ptr_tgt ); if( ptr_src == NULL ) { info->pted_src = NULL; info->flags_src = 0; ptr_tgt = TypeGetActualFlags( ptr_tgt, &info->flags_tgt ); info->pted_tgt = ptr_tgt; if( ptr_tgt->id == TYP_VOID ) { info->to_void = true; } if( NULL != orig_src && IntegralType( orig_src ) ) { info->reint_cast_ok = true; } ok = false; } else { first_level = true; const_always = true; info->reint_cast_ok = true; for( ; ; ) { type_flag flags_src; // source flags type_flag flags_tgt; // target flags type_flag cv_src; // source CV flags type_flag cv_tgt; // target CV flags ptr_src = TypeGetActualFlags( ptr_src, &flags_src ); ptr_tgt = TypeGetActualFlags( ptr_tgt, &flags_tgt ); cv_src = flags_src & TF1_CV_MASK; cv_tgt = flags_tgt & TF1_CV_MASK; if( cv_src != ( cv_tgt & cv_src ) ) { // test cv-containment if( first_level ) { info->cv_err_0 = true; // - diagnose elsewhere } else { ok = false; break; } } if( first_level ) { TYPE cl_src; // class for source TYPE cl_tgt; // class for target ok = true; info->pted_src = ptr_src; info->pted_tgt = ptr_tgt; info->flags_src = flags_src; info->flags_tgt = flags_tgt; cl_src = StructType( ptr_src ); if( ptr_tgt->id == TYP_VOID ) { info->to_void = true; // ok = (ptr_src == TYP_VOID); // break; } else if( NULL != cl_src ) { cl_tgt = StructType( ptr_tgt ); if( NULL != cl_tgt && cl_tgt != cl_src ) { if( TypeDerived( ptr_src, ptr_tgt ) ) { info->to_base = true; ok = false; // break; } else if( TypeDerived( ptr_tgt, ptr_src ) ) { info->to_derived = true; ok = false; // break; } } } else if( ( ptr_src->id != ptr_tgt->id ) && IntegralType( ptr_src ) && IntegralType( ptr_tgt ) && ( CgMemorySize( ptr_src ) == CgMemorySize( ptr_tgt ) ) ) { info->ptr_integral_ext = true; } if( !ok ) { if( info->cv_err_0 ) { info->reint_cast_ok = false; } break; } first_level = false; } if( cv_tgt != cv_src ) { // test const'ed to here if( ! const_always ) { info->reint_cast_ok = false; ok = false; break; } } if( (cv_tgt & TF1_CONST) == 0 ) { const_always = false; } if( ptr_src == ptr_tgt ) { ok = true; break; } if( TYP_FUNCTION == ptr_src->id || TYP_FUNCTION == ptr_tgt->id ) { ok = TypeCompareExclude( ptr_src , ptr_tgt , TC1_FUN_LINKAGE | TC1_NOT_ENUM_CHAR ); break; } ptr_src = TypePointedAtModified( ptr_src ); ptr_tgt = TypePointedAtModified( ptr_tgt ); if( NULL == ptr_src ) { if( NULL != ptr_tgt && NULL != FunctionDeclarationType( ptr_tgt ) ) { info->reint_cast_ok = false; } ok = false; break; } if( NULL == ptr_tgt ) { ok = false; break; } } } return( ok ); }
static void checkAutoReturn( // CHECK IF AUTOMATIC BEING RETURNED PTREE node, // - node to be checked TYPE ret_type ) // - return type { TYPE func_ret; // - type of function return SYMBOL func; // - function called SYMBOL comped; // - function being compiled PTREE expr; // - node for error TYPE refed; // - NULL ==> not reference comped = ScopeFunctionInProgress(); if( SymIsGenedFunc( comped ) ) { return; } expr = node; refed = TypeReference( ret_type ); for( ; ; ) { node = NodeRemoveCastsCommas( node ); if( ( node->op == PT_SYMBOL ) &&( SymIsAutomatic( node->u.symcg.symbol ) ) ) { if( NULL == refed ) { PTreeWarnExpr( expr, WARN_RET_ADDR_OF_AUTO ); } else { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } break; } else if( NodeIsBinaryOp( node, CO_DOT ) || NodeIsBinaryOp( node, CO_DOT_STAR ) ) { node = PTreeOpLeft( node ); } else if( NodeIsUnaryOp( node, CO_ADDR_OF ) ) { node = PTreeOpLeft( node ); } else if( NULL != refed ) { if( NodeIsBinaryOp( node, CO_DTOR ) ) { node = PTreeOpRight( node ); } else if( NodeIsBinaryOp( node, CO_CALL_EXEC ) ) { node = PTreeOpLeft( PTreeOpLeft( node ) ); if( node->op == PT_SYMBOL ) { func = node->u.symcg.symbol; if( SymIsCtor( func ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } else { func_ret = SymFuncReturnType( func ); if( NULL != StructType( func_ret ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } } } break; } else if( NodeIsBinaryOp( node, CO_CALL_EXEC_IND ) ) { func_ret = TypeFunctionCalled( NodeFuncForCall( node )->type ); func_ret = func_ret->of; if( NULL != StructType( func_ret ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } break; } else { break; } } else { break; } } }
PTREE AnalyseCall( // ANALYSIS FOR CALL PTREE expr, // - call expression CALL_DIAG *diagnostic ) // - diagnostics used for function problems { PTREE *r_args; // - reference( arguments ) PTREE *r_func; // - reference( function ) PTREE *ptlist; // - nodes for arguments PTREE left; // - left operand ( the function ) PTREE right; // - right operand ( the arguments ) PTREE this_node; // - node for "this" computation PTREE deref_args; // - member pointer dereference args PTREE last_arg; // - last argument PTREE static_fn_this; // - "this" for a static member PTREE templ_args; // - explicit template arguments SYMBOL sym; // - function symbol SYMBOL caller_sym; // - function that is doing the call TYPE type; // - temporary type TYPE fn_type; // - function type type_flag fn_mod; // - function modifier flags unsigned count; // - # args, caller arg_list *alist; // - arg_list for caller intrinsic_mapping *intr_map;// - mapping for intrinsic function SEARCH_RESULT *result; // - searching result boolean membptr_deref; // - TRUE ==> member pointer dereference boolean has_ellipsis; // - TRUE ==> ellipsis in argument list boolean virtual_call; // - TRUE ==> virtual call TEMP_PT_LIST default_list; // - default PTREE list TEMP_ARG_LIST default_args; // - default arg_list FNOV_DIAG fnov_diag; // - diagnosis information; r_args = PTreeRefRight( expr ); last_arg = *r_args; right = NodeReverseArgs( &count, last_arg ); *r_args = right; r_func = PTreeRefLeft( expr ); left = *r_func; membptr_deref = FALSE; this_node = NULL; intr_map = NULL; static_fn_this = NULL; virtual_call = FALSE; switch( left->cgop ) { case CO_DOT: case CO_ARROW: this_node = left->u.subtree[0]; left->u.subtree[0] = NULL; left = NodePruneTop( left ); *r_func = left; r_func = PTreeRefLeft( expr ); left = *r_func; if( ( left->op == PT_ID ) && ( left->cgop == CO_NAME_DTOR ) ) { /* dtor of a non-class type */ left = NodePruneTop( *r_func ); /* NYI: verify dtor call has no arguments */ expr->u.subtree[0] = NULL; NodeFreeDupedExpr( expr ); expr = NodeConvert( GetBasicType( TYP_VOID ), this_node ); expr = NodeComma( expr, left ); return( expr ); } break; case CO_CALL_EXEC_IND: if( left->flags & PTF_CALLED_ONLY ) { /* member pointer dereference being called */ deref_args = left->u.subtree[1]; this_node = NodeDupExpr( &(deref_args->u.subtree[1]) ); membptr_deref = TRUE; } break; } alist = ArgListTempAlloc( &default_args, count ); ptlist = PtListAlloc( default_list, count ); NodeBuildArgList( alist, ptlist, right, count ); if( this_node == NULL ) { alist->qualifier = FunctionThisQualifier(); } else { alist->qualifier = BaseTypeClassFlags( NodeType( this_node ) ); } if( NodeIsBinaryOp( left, CO_TEMPLATE ) ) { DbgAssert( left->u.subtree[0]->op == PT_SYMBOL ); templ_args = left->u.subtree[1]; left->u.subtree[1] = NULL; left = NodePruneTop( left ); *r_func = left; r_func = PTreeRefLeft( expr ); left = *r_func; } else { templ_args = NULL; } if( left->op == PT_SYMBOL ) { FNOV_RESULT ovret; SYMBOL orig; // - original symbol sym = left->u.symcg.symbol; orig = sym; if( left->cgop == CO_NAME_CONVERT ) { ovret = UdcOverloadedDiag( &sym , left->u.symcg.result , sym , SymFuncReturnType( sym ) , alist->qualifier , &fnov_diag ); } else { ovret = FuncOverloadedDiag( &sym , left->u.symcg.result , sym , alist , ptlist , templ_args , &fnov_diag ); } switch( ovret ) { case FNOV_AMBIGUOUS : CallDiagAmbiguous( expr, diagnostic->msg_ambiguous, &fnov_diag ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); case FNOV_NO_MATCH : if( this_node == NULL ) { if( SymIsThisFuncMember( orig ) ) { this_node = NodeThisCopyLocation( left ); } } if( this_node != NULL ) { if( ( ! SymIsCtor( orig ) ) &&( ! SymIsDtor( orig ) ) &&( CNV_OK != AnalysePtrCV ( this_node , TypeThisSymbol( orig , this_node->flags & PTF_LVALUE ) , NodeType( this_node ) , CNV_FUNC_THIS ) ) ) { PTreeErrorNode( expr ); InfSymbolDeclaration( orig ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } CallDiagNoMatch( expr , diagnostic->msg_no_match_one , diagnostic->msg_no_match_many , this_node , orig , &fnov_diag ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } FnovFreeDiag( &fnov_diag ); left->u.symcg.symbol = sym; result = left->u.symcg.result; if( this_node == NULL ) { if( SymIsThisFuncMember( sym ) ) { if( result->use_this ) { this_node = NodeThisCopyLocation( left ); if( this_node == NULL ) { PTreeErrorExpr( expr, ERR_INVALID_NONSTATIC_ACCESS ); InfSymbolDeclaration( sym ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } else { PTreeErrorExpr( expr, ERR_BARE_FUNCTION_ACCESS ); InfSymbolDeclaration( sym ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } } if( ! AnalyseSymbolAccess( expr, left, this_node, &diagAccess ) ) { NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } type = sym->sym_type; fn_type = TypeGetActualFlags( type, &fn_mod ); if( fn_type->flag & TF1_INTRINSIC ) { intr_map = intrinsicMapping( sym ); if( intr_map == NULL ) { outputCallTriggeredWarning( expr, sym ); } } if( fn_mod & TF1_FAR16 ) { /* we are calling a far16 function */ caller_sym = ScopeFunctionInProgress(); caller_sym->flag |= SF_FAR16_CALLER; } left->type = type; if( this_node == NULL ) { if( SymIsThisFuncMember( sym ) ) { this_node = NodeThisCopyLocation( left ); } } else { if( SymIsStaticFuncMember( sym ) ) { #ifdef OLD_STATIC_MEMBER_ACCESS NodeFreeDupedExpr( this_node ); #else static_fn_this = this_node; #endif this_node = NULL; } } if( this_node != NULL ) { TYPE pted; pted = TypePointedAtModified( this_node->type ); if( pted == NULL ) { pted = this_node->type; } if( TypeTruncByMemModel( pted ) ) { if( SymIsCtor( sym ) ) { PTreeErrorExpr( this_node, ERR_CTOR_OBJ_MEM_MODEL ); } else if( SymIsDtor( sym ) ) { PTreeErrorExpr( this_node, ERR_DTOR_OBJ_MEM_MODEL ); } else { PTreeErrorExpr( this_node, ERR_THIS_OBJ_MEM_MODEL ); } InfSymbolDeclaration( sym ); PTreeErrorNode( expr ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); NodeFreeDupedExpr( static_fn_this ); return( expr ); } if( adjustForVirtualCall( &this_node, r_func, result ) ) { virtual_call = TRUE; expr->cgop = CO_CALL_EXEC_IND; left = VfunSetupCall( expr->u.subtree[0] ); left = VfnDecorateCall( left, sym ); } else { expr->cgop = CO_CALL_EXEC; left = NodeUnaryCopy( CO_CALL_SETUP, expr->u.subtree[0] ); SymMarkRefed( sym ); } } else { NodeFreeSearchResult( left ); expr->cgop = CO_CALL_EXEC; left = NodeUnaryCopy( CO_CALL_SETUP, expr->u.subtree[0] ); SymMarkRefed( sym ); } } else { if( ! membptr_deref ) { /* i.e, p->foo() where foo is a pointer to a function */ NodeFreeDupedExpr( this_node ); this_node = NULL; } sym = NULL; left = expr->u.subtree[0]; type = TypedefModifierRemove( left->type ); if( type->id == TYP_POINTER ) { type = type->of; } fn_type = TypeGetActualFlags( type, &fn_mod ); if( fn_mod & TF1_FAR16 ) { /* we are calling a far16 function */ caller_sym = ScopeFunctionInProgress(); caller_sym->flag |= SF_FAR16_CALLER; } if( ! TypeHasNumArgs( type, count ) ) { PTreeErrorExpr( expr, ERR_PARM_COUNT_MISMATCH_POINTER ); CErr2p( INF_FUNCTION_TYPE, type ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); NodeFreeDupedExpr( static_fn_this ); return( expr ); } expr->cgop = CO_CALL_EXEC_IND; left = VfunSetupCall( left ); } expr->u.subtree[0] = left; #if _CPU == _AXP if( intr_map != NULL && intr_map->cgop == CO_VASTART ) { expr = convertVaStart( expr, alist, type ); } else { expr = NodeConvertCallArgList( expr, count, type, &expr->u.subtree[1] ); } #else expr = NodeConvertCallArgList( expr, count, type, &expr->u.subtree[1] ); #endif if( expr->op != PT_ERROR ) { TYPE ftype; // - function type PTREE cdtor; // - CDTOR node PTREE callnode; // - call node PTREE retnnode; // - return node (for struct return) callnode = expr; if( this_node == NULL ) { cdtor = NULL; } else { this_node = NodeArg( this_node ); if( virtual_call ) { this_node->flags |= PTF_ARG_THIS_VFUN; } if( sym != NULL && SymIsDtor( sym ) ) { cdtor = NodeArg( NodeCDtorArg( DTOR_NULL ) ); } else { cdtor = NULL; } } ftype = type; type = TypedefModifierRemove( type ); has_ellipsis = TypeHasEllipsisArg( type ); type = type->of; { TYPE tgt = TypeReference( type ); if( tgt == NULL ) { expr->type = type; } else { expr->type = tgt; expr->flags |= PTF_LVALUE; } } if( sym != NULL ) { if( ! AddDefaultArgs( sym, expr ) ) { NodeFreeDupedExpr( cdtor ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return expr; } } if( NULL != TypeReference( type ) ) { expr->flags |= PTF_LVALUE; } if( OMR_CLASS_REF == ObjModelArgument( type ) ) { retnnode = NodeTemporary( type ); retnnode = PTreeCopySrcLocation( retnnode, expr ); } else { retnnode = NULL; } expr = CallArgsArrange( ftype , callnode , callnode->u.subtree[1] , this_node , cdtor , retnnode ); if( retnnode != NULL ) { expr = NodeDtorExpr( expr, retnnode->u.symcg.symbol ); if( SymRequiresDtoring( retnnode->u.symcg.symbol ) ) { expr = PtdCtoredExprType( expr, NULL, type ); } } type = StructType( type ); if( type != NULL && ! TypeDefined( type ) ) { PTreeErrorExpr( expr, ERR_RETURN_UNDEFD_TYPE ); } if( intr_map != NULL && expr->op != PT_ERROR ) { #if _CPU == _AXP if( intr_map->cgop == CO_VASTART ) { expr = transformVaStart( expr ); } else { expr = PTreeIntrinsicOperator( expr, intr_map->cgop ); } #else expr = PTreeIntrinsicOperator( expr, intr_map->cgop ); #endif expr->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF; } } if( static_fn_this != NULL ) { expr = NodeCommaIfSideEffect( static_fn_this, expr ); } ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return expr; }
PTREE NodeConvertCallArgList( // CONVERT CALL ARGUMENT LIST, AS REQ'D PTREE call_expr, // - call expression (for errors only) unsigned acount, // - # args, caller TYPE type, // - function type PTREE *args ) // - addr( caller argument nodes ) { PTREE arg; // - caller argument nodes arg_list *plist; // - prototype arguments unsigned count; // - # args, processed unsigned pcount; // - # args, prototype TYPE *pptr; // - prototype type ptr. TYPE proto; // - prototype arg. type boolean extern_c_fun; // - TRUE ==> extern "C" function TEMP_TYPE old; // - old default class for temp.s if( call_expr != NULL && call_expr->op != PT_ERROR && acount > 0 ) { old = TemporaryClass( TEMP_TYPE_EXPR ); plist = TypeArgList( type ); pptr = plist->type_list; pcount = plist->num_args; type = FunctionDeclarationType( type ); if( TypeHasEllipsisArg( type ) ) { for( count = 1 ; count <= acount ; ++count, args = &arg->u.subtree[0] ) { arg = PTreeOp( args ); if( ! ( count < pcount ? arg_convert( arg, *pptr++ ) : convertEllipsisArg( arg ) ) ) { PTreeErrorNode( call_expr ); break; } } } else { if( type->flag & TF1_PLUSPLUS ) { extern_c_fun = FALSE; } else { extern_c_fun = TRUE; } for( count = 1 ; count <= acount ; ++count, args = &arg->u.subtree[0] ) { TYPE cl_type; arg = PTreeOp( args ); proto = *pptr++; if( ! arg_convert( arg, proto ) ) { PTreeErrorNode( call_expr ); break; } cl_type = StructType( proto ); if( NULL != cl_type ) { if( extern_c_fun ) { if( ! passStructOnStack( arg , WARN_EXTERN_C_CLASS_ARG ) ) { PTreeErrorNode( call_expr ); break; } } else if( OMR_CLASS_VAL == ObjModelArgument( cl_type ) ) { passStructOnStack( arg, ERR_CALL_WATCOM ); } } } } TemporaryClass( old ); } return( call_expr ); }