static void declareParameter( // DEFINE A FUNCTION PARAMETER SYMBOL sym ) // - the parameter { cg_type cgtype; // - type for code generator FN_CTL* fctl; // - function information TYPE ftype; // - function type if( sym != NULL ) { fctl = FnCtlTop(); ftype = FunctionDeclarationType( fctl->func->sym_type ); sym = inlineSymbol( sym ); if( ( TF1_PLUSPLUS & ftype->flag ) && OMR_CLASS_REF == ObjModelArgument( sym->sym_type ) ) { cgtype = TY_POINTER; } else { cgtype = CgTypeOutput( sym->sym_type ); } CGParmDecl( (cg_sym_handle)sym, cgtype ); if( fctl->debug_info && ( GenSwitches & DBG_LOCALS ) ) { if( GenSwitches & DBG_DF ){ DwarfSymDebugGenSymbol( sym, true, cgtype == TY_POINTER ); }else{ SymbolicDebugGenSymbol( sym, true, cgtype == TY_POINTER ); } } IbpDefineSym( fctl->handle, sym ); } }
void CgDeclParms( // DEFINE ARGS FOR CURRENT FN IN CORRECT ORDER FN_CTL *fctl, // - current function control pointer SCOPE scope ) // - argument scope { SYMBOL curr; SYMBOL stop; SYMBOL *psym; // - addr[ parameter symbol ] TYPE fn_type; auto VSTK_CTL sym_stack; SYMBOL ret_sym; NAME ret_name; fn_type = FunctionDeclarationType( fctl->func->sym_type ); VstkOpen( &sym_stack, sizeof( SYMBOL ), 16 ); stop = ScopeOrderedStart( scope ); ret_name = CppSpecialName( SPECIAL_RETURN_VALUE ); ret_sym = NULL; curr = NULL; for(;;) { curr = ScopeOrderedNext( stop, curr ); if( curr == NULL ) break; if( ( curr->name != NULL ) && ( ret_name == curr->name->name ) ) { ret_sym = curr; } else { psym = VstkPush( &sym_stack ); *psym = curr; } } IbpDefineParms(); declareParameter( fctl->this_sym ); declareParameter( fctl->cdtor_sym ); declareParameter( ret_sym ); switch( PcCallImpl( fn_type ) ) { case CALL_IMPL_REV_CPP : case CALL_IMPL_REV_C : for(;;) { psym = VstkPop( &sym_stack ); if( psym == NULL ) break; declareParameter( *psym ); } break; case CALL_IMPL_CPP : case CALL_IMPL_C : case CALL_IMPL_ELL_CPP : case CALL_IMPL_ELL_C : { unsigned index; // - parameter index unsigned max_parms; // - # parameters SYMBOL *psym1; // - addr[ parameter symbol ] max_parms = VstkDimension( &sym_stack ); for( index = 0; index < max_parms; ++index ) { psym1 = VstkIndex( &sym_stack, index ); declareParameter( *psym1 ); } } break; } VstkClose( &sym_stack ); CGLastParm(); }
TYPE TypeFunctionCalled( // GET FUNCTION DECLARATION TYPE CALLED TYPE type ) // - function type called { TYPE pted; // - NULL or type pointed at type = TypeReferenced( type ); pted = TypePointedAtModified( type ); if( NULL != pted ) { type = pted; } return( FunctionDeclarationType( type ) ); }
cg_type CgFuncRetnType( // GET CG RETURN TYPE FOR A FUNCTION SYMBOL func ) // - function { TYPE ftype; // - type for function cg_type cgtype; // - codegen type ftype = FunctionDeclarationType( func->sym_type ); if( OMR_CLASS_REF == ObjModelFunctionReturn( ftype ) ) { cgtype = TY_POINTER; } else { cgtype = prcCgType( CgTypeOutput( ftype->of ) ); } return cgtype; }
static TYPE canonicalPtrType( // GET CANONICAL PTR TYPE TYPE type ) // - type { TYPE test; // - used to test type test = PointerTypeEquivalent( type ); if( test == NULL ) { type = canonicalBaseType( type ); } else if( FunctionDeclarationType( test ) ) { type = MakePointerTo( canonicalBaseType( test ) ); } else { type = MakePointerTo( canonicalBaseType( test->of ) ); } return type; }
bool TypeIsCppFunc( // TEST IF C++ FUNCTION TYPE TYPE type ) // - type to be tested { bool ok; // - return: true ==> C++ function type = FunctionDeclarationType( type ); if( type == NULL ) { ok = false; } else if( type->flag & TF1_PLUSPLUS ) { ok = true; } else { ok = false; } return( ok ); }
static void fmtSymOpName( SYMBOL sym, VBUF *pvbuf ) /*************************************************/ { VBUF prefix, suffix; TYPE type; VbufInit( pvbuf ); type = FunctionDeclarationType( sym->sym_type ); if( type != NULL ) { FormatFunctionType( type->of , &prefix , &suffix , 0 , FormatTypeDefault | FF_TYPEDEF_STOP ); VbufConcVbufRev( pvbuf, &suffix ); VbufTruncWhite( pvbuf ); VbufConcVbufRev( pvbuf, &prefix ); VbufFree( &prefix ); VbufFree( &suffix ); } }
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; }
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 ); }
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 ); }
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; }