static void dumpMember( // DUMP A MEMBER SYMBOL memb, // - member void *_di ) // - dump information { DUMP_INFO* di = _di; target_offset_t offset; // - offset of symbol TYPE type; // - type of symbol NAME name; // - symbol's name offset = di->offset + memb->u.member_offset; name = memb->name->name; type = TypedefModifierRemove( memb->sym_type ); if( type->id == TYP_BITFIELD ) { di = dumpBitMemb( di , "bit member:" , NameStr( name ) , offset , type->u.b.field_start , type->u.b.field_width ); } else { di = dumpDataMemb( di , "member:" , NameStr( name ) , offset , CgMemorySize( type ) ); } }
bool IsCgTypeAggregate( // CAN TYPE CAN BE INITIALIZED AS AGGREGATE? TYPE type, // - C++ type bool string ) // - array of string not aggregate { bool retb = false; // - true if aggregate CLASSINFO *info; // - info part of class type type = TypedefModifierRemove( type ); switch( type->id ) { case TYP_ARRAY : if( string && TypeIsCharString( type ) ) break; retb = true; break; case TYP_BITFIELD : retb = true; break; case TYP_CLASS : info = type->u.c.info; if( info->corrupted ) break; if( info->bases != NULL ) break; if( info->size != type->u.c.info->vsize ) break; if( info->last_vfn != 0 ) break; if( info->last_vbase != 0 ) break; if( info->has_data == 0 ) break; if( info->has_ctor != 0 ) break; retb = true; break; } return( retb ); }
PC_CALLIMPL PcCallImpl( // OBTAIN PC CALL IMPLEMENTATION TYPE ftype ) // - function type { PC_CALLIMPL retn; // - type of call implemented ftype = TypedefModifierRemove( ftype ); if( TypeHasReverseArgs( ftype ) ) { if( ftype->flag & TF1_PLUSPLUS ) { retn = CALL_IMPL_REV_CPP; } else { retn = CALL_IMPL_REV_C; } } else if( TypeHasEllipsisArg( ftype ) ) { if( ftype->flag & TF1_PLUSPLUS ) { retn = CALL_IMPL_ELL_CPP; } else { retn = CALL_IMPL_ELL_C; } } else { if( ftype->flag & TF1_PLUSPLUS ) { retn = CALL_IMPL_CPP; } else { retn = CALL_IMPL_C; } } return retn; }
target_size_t ArrayTypeNumberItems( // GET ACTUAL NUMBER OF ITEMS FOR AN ARRAY TYPE artype ) // - an array type { target_size_t count; // - counts number of items for( count = 1; ; artype = artype->of ) { artype = TypedefModifierRemove( artype ); if( artype->id != TYP_ARRAY ) break; count *= artype->u.a.array_size; } return count; }
TYPE PointerTypeEquivalent( TYPE type ) /*************************************/ { type = TypedefModifierRemove( type ); switch( type->id ) { case TYP_POINTER: /* this allows references also */ case TYP_ARRAY: case TYP_FUNCTION: return( type ); } return( NULL ); }
static PTREE castFloatingConstant( PTREE expr, TYPE type, bool *happened ) { target_long value; PTREE new_expr; type_id id; id = TypedefModifierRemove( type )->id; switch( id ) { case TYP_POINTER: case TYP_MEMBER_POINTER: id = TYP_ULONG; // drops thru case TYP_SCHAR: case TYP_SSHORT: case TYP_SINT: case TYP_SLONG: case TYP_UCHAR: case TYP_USHORT: case TYP_UINT: case TYP_ULONG: case TYP_WCHAR: value = BFGetLong( &(expr->u.floating_constant) ); new_expr = PTreeIntConstant( (target_ulong) value, id ); new_expr = CastIntConstant( new_expr, type, happened ); break; case TYP_FLOAT: { float_handle flt_val; flt_val = BFCopy( expr->u.floating_constant ); new_expr = PTreeFloatingConstant( flt_val, id ); } break; case TYP_LONG_DOUBLE: case TYP_DOUBLE: { float_handle flt_val; flt_val = BFCopy( expr->u.floating_constant ); new_expr = PTreeFloatingConstant( flt_val, id ); } break; case TYP_SLONG64: case TYP_ULONG64: { signed_64 val = BFCnvF64( expr->u.floating_constant ); new_expr = PTreeInt64Constant( val, id ); } break; default: return( expr ); } *happened = true; new_expr = PTreeCopySrcLocation( new_expr, expr ); PTreeFree( expr ); return( new_expr ); }
cg_type CgGetCgType( // GET CODEGEN TYPE TYPE type ) // - type { TYPE basic; // - basic type cg_type cgtype; // - codegen type basic = TypedefModifierRemove( type ); if( basic->id == TYP_CLASS ) { if( OMR_CLASS_VAL == ObjModelArgument( basic ) ) { cgtype = prcCgType( CgTypeOutput( type ) ); } else { cgtype = TY_POINTER; } } else { cgtype = prcCgType( CgTypeOutput( type ) ); } return cgtype; }
bool PointerToFuncEquivalent( // TEST IF EQUIVALENT TO PTR(FUNCTION) TYPE type ) { bool ok; // - return: true ==> equiv. to ptr to funct. type_flag not_used; ok = false; type = TypedefModifierRemove( type ); if( type->id == TYP_FUNCTION ) { ok = true; } else if( PointerTypeEquivalent( type ) ) { type = TypePointedAt( type, ¬_used ); if( type->id == TYP_FUNCTION ) { ok = true; } } return( ok ); }
static PTREE castConstant( PTREE expr, TYPE type, bool *happened ) { TYPE type_final; *happened = false; if( notFoldable( expr ) ) { return( expr ); } type_final = TypedefModifierRemoveOnly( type ); type = TypedefModifierRemove( type_final ); switch( expr->op ) { case PT_INT_CONSTANT: expr = CastIntConstant( expr, type, happened ); expr->type = type_final; break; case PT_FLOATING_CONSTANT: expr = castFloatingConstant( expr, type, happened ); expr->type = type_final; break; } return( expr ); }
static target_size_t cgTypeTruncSize( // GET SIZE FOR TRUNCATION TYPE type ) // - type to be sized { target_size_t size; // - size of element type_flag flags; // - flags for a type switch( TypedefModifierRemove( type )->id ) { case TYP_ARRAY : case TYP_FUNCTION : case TYP_POINTER : TypePointedAt( type, &flags ); if( flags & ( TF1_BASED | TF1_FAR16 ) ) { type = TypeConvertFromPcPtr( type ); } size = cgPtrSize( type ); break; default : size = CgTypeSize( type ); break; } return( size ); }
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; }
TYPE CgStripType( // STRIP ONE LEVEL OF TYPE INFORMATION TYPE type ) // - type { return( TypedefModifierRemove( type )->of ); }
static type_id integralPromote( // GET type_id AFTER INTEGRAL PROMOTION TYPE type ) // - original type { return( intPromo[TypedefModifierRemove( type )->id] ); }
static boolean convertEllipsisArg(// CONVERT AN ELLIPSIS (...) ARGUMENT PTREE arg ) // - argument { boolean retn; // - return: TRUE ==> ok PTREE right; // - argument PTREE afun; // - &[ function ] TYPE type; // - node type switch( NodeAddrOfFun( PTreeOpRight( arg ), &afun ) ) { case ADDR_FN_MANY : case ADDR_FN_MANY_USED : PTreeErrorExpr( arg->u.subtree[1], ERR_ELLIPSE_ADDR_OVERLOAD ); retn = FALSE; break; default : right = NodeRvalue( arg->u.subtree[1] ); arg->u.subtree[1] = right; type = TypedefModifierRemove( right->type ); switch( type->id ) { case TYP_CHAR : case TYP_SCHAR : case TYP_UCHAR : case TYP_SSHORT : case TYP_WCHAR : case TYP_USHORT : type = TypeUnArithResult( type ); right = NodeConvert( type, right ); arg_finish( right, arg ); retn = TRUE; break; case TYP_FLOAT : type = GetBasicType( TYP_DOUBLE ); right = NodeConvert( type, right ); arg_finish( right, arg ); retn = TRUE; break; case TYP_ARRAY : type = PointerTypeForArray( right->type ); right = NodeConvert( type, right ); arg_finish( right, arg ); retn = TRUE; break; case TYP_MEMBER_POINTER : ConvertMembPtrConst( &arg->u.subtree[1] ); arg_fillout( arg ); retn = TRUE; break; case TYP_POINTER : if( NULL == FunctionDeclarationType( type->of ) ) { type_flag def_flags; type_flag act_flags; type_flag arg_flags; TYPE base_type; PTREE cnv; base_type = TypeGetActualFlags( type->of, &arg_flags ); act_flags = arg_flags & TF1_MEM_MODEL; def_flags = DefaultMemoryFlag( type->of ); if( ( ( def_flags & TF1_FAR ) &&( act_flags != TF1_HUGE ) &&( act_flags != TF1_FAR ) ) ||( ( def_flags & TF1_HUGE ) &&( act_flags != TF1_HUGE ) ) ) { type = MakeModifiedType( base_type , ( arg_flags & ~TF1_MEM_MODEL ) | def_flags ); type = MakePointerTo( type ); cnv = CastImplicit( arg->u.subtree[1] , type , CNV_EXPR , NULL ); arg->u.subtree[1] = cnv; DbgVerify( PT_ERROR != cnv->op , "convertEllipsisArg -- failed ptr.cnv" ); arg_fillout( arg ); retn = TRUE; } else { arg_fillout( arg ); retn = TRUE; } } else { arg_fillout( arg ); retn = TRUE; } break; case TYP_CLASS : retn = passStructOnStack( arg, WARN_ELLIPSIS_CLASS_ARG ); break; default : arg_fillout( arg ); retn = TRUE; break; } break; } return retn; }
PTREE CastIntConstant( PTREE expr, TYPE type, bool *happened ) { PTREE new_expr; target_ulong ul_val; float_handle dbl_val; type_id id; bool signed_type; signed_type = SignedIntType( expr->type ); id = TypedefModifierRemove( type )->id; ul_val = expr->u.uint_constant; if( NULL == Integral64Type( expr->type ) ) { switch( id ) { case TYP_SCHAR: ul_val = (target_schar) ul_val; /* fall through */ case TYP_SSHORT: ul_val = (target_short) ul_val; /* fall through */ case TYP_SINT: ul_val = (target_int) ul_val; /* fall through */ case TYP_SLONG: ul_val = (target_long) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_UCHAR: ul_val = (target_uchar) ul_val; /* fall through */ case TYP_USHORT: ul_val = (target_ushort) ul_val; /* fall through */ case TYP_UINT: ul_val = (target_uint) ul_val; /* fall through */ case TYP_ULONG: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_ULONG64: case TYP_SLONG64: if( PT_FLOATING_CONSTANT == expr->op ) { new_expr = PTreeInt64Constant ( BFCnvF64( expr->u.floating_constant ) , id ); } else { new_expr = PTreeInt64Constant( expr->u.int64_constant, id ); } break; case TYP_POINTER: case TYP_MEMBER_POINTER: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, TYP_ULONG ); new_expr->type = type; break; case TYP_FLOAT: #if 0 // these are now identical, with canonical floating point if( signed_type ) { flt_val = BFCnvIF( expr->u.int_constant ); } else { flt_val = BFCnvUF( expr->u.uint_constant ); } new_expr = PTreeFloatingConstant( flt_val, id ); break; #endif case TYP_LONG_DOUBLE: case TYP_DOUBLE: if( signed_type ) { dbl_val = BFCnvIF( expr->u.int_constant ); } else { dbl_val = BFCnvUF( expr->u.uint_constant ); } new_expr = PTreeFloatingConstant( dbl_val, id ); break; case TYP_WCHAR: ul_val = (target_wchar) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; default: return( expr ); } } else { ul_val = expr->u.int_constant; switch( id ) { case TYP_SCHAR: ul_val = (target_schar) ul_val; /* fall through */ case TYP_SSHORT: ul_val = (target_short) ul_val; /* fall through */ case TYP_SINT: ul_val = (target_int) ul_val; /* fall through */ case TYP_SLONG: ul_val = (target_long) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_SLONG64: case TYP_ULONG64: new_expr = PTreeInt64Constant( expr->u.int64_constant, id ); break; case TYP_UCHAR: ul_val = (target_uchar) ul_val; /* fall through */ case TYP_USHORT: ul_val = (target_ushort) ul_val; /* fall through */ case TYP_UINT: ul_val = (target_uint) ul_val; /* fall through */ case TYP_ULONG: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_POINTER: case TYP_MEMBER_POINTER: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, TYP_ULONG ); new_expr->type = type; break; case TYP_FLOAT: #if 0 // these are now identical, with canonical floating point if( signed_type ) { flt_val = BFCnvI64F( expr->u.int64_constant ); } else { flt_val = BFCnvU64F( expr->u.uint64_constant ); } new_expr = PTreeFloatingConstant( flt_val, id ); break; #endif case TYP_LONG_DOUBLE: case TYP_DOUBLE: if( signed_type ) { dbl_val = BFCnvI64F( expr->u.int64_constant ); } else { dbl_val = BFCnvU64F( expr->u.int64_constant ); } new_expr = PTreeFloatingConstant( dbl_val, id ); break; case TYP_WCHAR: ul_val = (target_wchar) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; default: return( expr ); } } *happened = true; new_expr->flags = expr->flags; new_expr = PTreeCopySrcLocation( new_expr, expr ); PTreeFree( expr ); return( new_expr ); }
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; }
void DumpObjectModelEnum( // DUMP OBJECT MODEL: ENUM TYPE type ) // - enum type { SYMBOL sym; // - current symbol TYPE base; // - base type VBUF buffer; // - printing buffer char buf[16]; // - buffer int numb; // - a numeric value const char *name; // - name to be printed bool sign; // - TRUE ==> signed enum unsigned mask; // - used to mask to true size unsigned val; // - value as unsigned CompFlags.log_note_msgs = TRUE; base = TypedefModifierRemoveOnly( type ); sym = base->u.t.sym; VbufInit( &buffer ); VbufConcStr( &buffer, "Object Model for: " ); if( NULL == sym->name->name || NameStr( sym->name->name )[0] == '.' ) { VbufConcStr( &buffer, "anonymous enum type" ); } else { VbufConcStr( &buffer, NameStr( sym->name->name ) ); } switch( TypedefModifierRemove( base->of ) -> id ) { case TYP_CHAR : case TYP_UCHAR : name = "unsigned char"; sign = FALSE; break; case TYP_SCHAR : name = "signed char"; sign = TRUE; break; case TYP_SSHORT : name = "signed short"; sign = TRUE; break; case TYP_USHORT : name = "unsigned short"; sign = FALSE; break; case TYP_SINT : name = "signed int"; sign = TRUE; break; case TYP_UINT : name = "unsigned int"; sign = FALSE; break; case TYP_SLONG : name = "signed long"; sign = TRUE; break; case TYP_ULONG : name = "unsigned long"; sign = FALSE; break; case TYP_SLONG64 : name = "__int64"; sign = TRUE; break; case TYP_ULONG64 : name = "unsigned __int64"; sign = FALSE; break; DbgDefault( "DumpObjectModelEnum -- bad underlying type" ); } VbufConcStr( &buffer, ", base type is " ); VbufConcStr( &buffer, name ); vbufWrite( &buffer ); mask = CgMemorySize( base ); if( mask == sizeof( unsigned ) ) { mask = -1; } else { mask = ( 1 << ( mask * 8 ) ) - 1; } for( ; ; ) { sym = sym->thread; if( ! SymIsEnumeration( sym ) ) break; VbufRewind( &buffer ); VbufConcStr( &buffer, " " ); VbufConcStr( &buffer, NameStr( sym->name->name ) ); VbufConcStr( &buffer, " = " ); numb = sym->u.sval; if( sign && numb < 0 ) { VbufConcChr( &buffer, '-' ); VbufConcDecimal( &buffer, -numb ); } else { VbufConcDecimal( &buffer, numb ); } val = mask & numb; if( val > 10 ) { itoa( val, buf, 16 ); VbufConcStr( &buffer, " /0x" ); VbufConcStr( &buffer, buf ); } vbufWrite( &buffer ); } VbufFree( &buffer ); CompFlags.log_note_msgs = FALSE; }