示例#1
0
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, &not_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 );
}
示例#2
0
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 );
}
示例#3
0
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 );
}
示例#4
0
static TYPE arrayOrStructType   // PUT TYPE INTO CONICAL FORM
    ( TYPE type )               // - the type
{
    TYPE retn = StructType( type );
    if( NULL == retn ) {
        retn = ArrayType( type );
    }
    return retn;
}
示例#5
0
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 );
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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 );
}
示例#9
0
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
    }
示例#10
0
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, &not_used ) );
            if( NULL != cl_type && !TypeDefined( cl_type ) ) {
                InfMsgPtr( INF_CLASS_NOT_DEFINED, cl_type );
            }
        }
    }
}
示例#11
0
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);
        }
    }
}
示例#12
0
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();
    }
}
示例#13
0
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 );
}
示例#14
0
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;
        }
    }
}
示例#15
0
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;
}
示例#16
0
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 );
}