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 ); } } } }
bool TypeDefedNonAbstract // REQUIRE DEFINED, NON-ABSTRACT TYPE ( TYPE type // - the type , PTREE expr // - NULL or expression for error , MSG_NUM msg_abstract // - message when abstract , MSG_NUM msg_undefed ) // - message when undefined { bool retb; // - return: true ==> defined & non-abstract expr = expr; retb = false; if( ! TypeDefined( type ) ) { CErr1( msg_undefed ); InfClassDecl( type ); } else if( AbstractClassType( type ) ) { CErr1( msg_abstract ); InfClassDecl( type ); ScopeNotePureFunctions( type ); } else { retb = true; } return( retb ); }
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(); } }
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; }
static target_size_t cgSize( // COMPUTE SIZE OF A TYPE TYPE type, // - type bool ref_as_ptr ) // - true ==> treat reference as pointer { type_flag mod_flags; // - modifier flags target_size_t size; // - size of type type = TypeModFlags( type, &mod_flags ); switch( type->id ) { case TYP_BOOL : size = TARGET_BOOL; break; case TYP_ERROR : case TYP_UCHAR : case TYP_SCHAR : size = TARGET_CHAR; break; case TYP_WCHAR : case TYP_USHORT : case TYP_SSHORT : size = TARGET_SHORT; break; case TYP_SINT : size = TARGET_INT; break; case TYP_UINT : size = TARGET_UINT; break; case TYP_ULONG : size = TARGET_ULONG; break; case TYP_SLONG : size = TARGET_LONG; break; case TYP_ULONG64 : size = TARGET_ULONG64; break; case TYP_SLONG64 : size = TARGET_LONG64; break; case TYP_FLOAT : size = TARGET_FLOAT; break; case TYP_DOUBLE : size = TARGET_DOUBLE; break; case TYP_LONG_DOUBLE : size = TARGET_LONG_DOUBLE; break; case TYP_POINTER : if( ( ! ref_as_ptr ) && ( type->flag & TF1_REFERENCE ) ) { size = cgSize( type->of, false ); } else { type = TypeModFlags( type->of, &mod_flags ); if( type->id == TYP_FUNCTION ) { size = code_ptr_size( mod_flags ); } else { size = data_ptr_size( mod_flags ); } } break; case TYP_BITFIELD : size = cgSize( type->of, true ); break; case TYP_ARRAY : size = type->u.a.array_size; if( type->flag & TF1_ZERO_SIZE ) { DbgAssert( type->u.a.array_size == 1 ); size = 0; } else { size *= cgSize( type->of, false ); } break; case TYP_CLASS : if( TypeDefined( type ) ) { size = type->u.c.info->size; } else { size = 0; } break; case TYP_FUNCTION : size = code_ptr_size( mod_flags ); break; case TYP_MEMBER_POINTER : size = CgCodePtrSize() + 2 * TARGET_UINT; break; default : size = 0; break; } return( size ); }