コード例 #1
0
void    CkComSize( sym_id sym_ptr, unsigned_32 size ) {
//=====================================================

// Check for matching sizes of common blocks.

    char        buff[MAX_SYMLEN+1];
    intstar4    com_size;

    com_size = GetComBlkSize( sym_ptr );
    if( size != com_size ) {
        if( size > com_size ) {
            SetComBlkSize( sym_ptr, size );
        }
        if( ( sym_ptr->ns.flags & SY_COMSIZE_WARN ) == 0 ) {
            // It's nice to give a warning message when the blank common
            // block appears as different sizes even though the standard
            // permits it.
            if( sym_ptr->ns.flags & SY_BLANK_COMMON ) {
                Warning( CM_BLANK_DIFF_SIZE );
            } else {
                STGetName( sym_ptr, buff );
                Warning( CM_NAMED_DIFF_SIZE, buff );
            }
            sym_ptr->ns.flags |= SY_COMSIZE_WARN;
        }
    }
}
コード例 #2
0
sym_id  AddCB2GList( sym_id ste_ptr ) {
//=====================================

// Add a common block to the global list.

    sym_id      gbl;
    unsigned_16 flags;

    flags = ste_ptr->ns.flags;
    gbl = SearchGList( ste_ptr );
    if( gbl == NULL ) {
        gbl = LnkNewGlobal( ste_ptr );
    } else if( ( gbl->ns.flags & SY_CLASS ) != SY_COMMON ) {
        PrevDef( gbl );
    } else {
        if( ( gbl->ns.flags & SY_SAVED ) != ( flags & SY_SAVED ) ) {
            gbl->ns.flags |= SY_SAVED;
            if( ( flags & SY_COMMON_LOAD ) == 0 ) {
                NameWarn( SA_COMMON_NOT_SAVED, ste_ptr );
            }
        }
        CkComSize( gbl, GetComBlkSize( ste_ptr ) );
        if( flags & gbl->ns.flags & SY_IN_BLOCK_DATA ) {
            NameErr( CM_BLKDATA_ALREADY, gbl );
        }
        gbl->ns.flags |= flags & ( SY_COMMON_INIT | SY_EQUIVED_NAME );
    }
    return( gbl );
}
コード例 #3
0
cg_type SymPtrType( sym_id sym ) {
//================================

// Get type of pointer required to address given symbol.

    sym_id      leader;
    cg_type     p_type;
    signed_32   offset;
    com_eq      *ce_ext;
    unsigned_32 item_size;
    segment_id  leader_seg;
    unsigned_16 flags;

    flags = sym->ns.flags;
    if( flags & SY_SUB_PARM ) {
        // subprogram argument
        if( ( flags & SY_CLASS ) == SY_SUBPROGRAM ) {
            p_type = TY_CODE_PTR;
        } else if( flags & SY_SUBSCRIPTED ) {
            p_type = ArrayPtrType( sym );
        } else {
            p_type = TY_GLOBAL_POINTER;
        }
    } else if( flags & SY_IN_EQUIV ) {
        leader = sym;
        offset = 0;
        for(;;) {
            ce_ext = leader->ns.si.va.vi.ec_ext;
            if( ce_ext->ec_flags & LEADER ) break;
            offset += ce_ext->offset;
            leader = ce_ext->link_eqv;
        }
        if( ce_ext->ec_flags & MEMBER_IN_COMMON ) {
            offset += ce_ext->offset;
            if( GetComBlkSize( ce_ext->com_blk ) <= MaxSegSize ) {
                // common block fits in a segment
                p_type = TY_GLOBAL_POINTER;
            } else {
                item_size = _SymSize( sym );
                if( flags & SY_SUBSCRIPTED ) {
                    item_size *= sym->ns.si.va.dim_ext->num_elts;
                }
                if( offset + item_size <= MaxSegSize ) {
                    // object fits in first segment of common block
                    // (common block label is at start of first segment)
                    p_type = TY_GLOBAL_POINTER;
                } else {
                    p_type = TY_HUGE_POINTER;
                }
            }
        } else {
            if( ce_ext->high - ce_ext->low <= MaxSegSize ) {
                // equivalence set fits in a segment
                p_type = TY_GLOBAL_POINTER;
            } else {
                item_size = _SymSize( sym );
                if( flags & SY_SUBSCRIPTED ) {
                    item_size *= sym->ns.si.va.dim_ext->num_elts;
                }
                leader_seg = GetGlobalSeg( ce_ext->offset );
                offset += ce_ext->offset;
                if( ( GetGlobalSeg( offset ) == leader_seg ) &&
                    ( GetGlobalSeg( offset + item_size ) == leader_seg ) ) {
                    // the entire item is in the same segment as the leader
                    p_type = TY_GLOBAL_POINTER;
                } else {
                    p_type = TY_HUGE_POINTER;
                }
            }
        }
    } else if( flags & SY_IN_COMMON ) {
        ce_ext = sym->ns.si.va.vi.ec_ext;
        if( GetComBlkSize( ce_ext->com_blk ) <= MaxSegSize ) {
            // common block fits in a segment
            p_type = TY_GLOBAL_POINTER;
        } else {
            item_size = _SymSize( sym );
            if( flags & SY_SUBSCRIPTED ) {
                item_size *= sym->ns.si.va.dim_ext->num_elts;
            }
            if( ce_ext->com_blk->ns.flags & SY_EQUIVED_NAME ) {
                if( ce_ext->offset + item_size <= MaxSegSize ) {
                    // object fits in first segment of common block
                    // (common block label is at start of first segment)
                    p_type = TY_GLOBAL_POINTER;
                } else {
                    p_type = TY_HUGE_POINTER;
                }
            } else {
                // each symbol in common block gets a label at the offset into
                // the common block
                if( GetComOffset( ce_ext->offset ) + item_size <= MaxSegSize ) {
                    // object fits in a segment
                    p_type = TY_GLOBAL_POINTER;
                } else {
                    p_type = TY_HUGE_POINTER;
                }
            }
        }
    } else if( ( flags & SY_SUBSCRIPTED ) && _Allocatable( sym ) ) {
        p_type = ArrayPtrType( sym );
    } else if( ( flags & SY_SUBSCRIPTED ) || ( sym->ns.typ == FT_STRUCTURE ) ) {
        item_size = _SymSize( sym );
        if( flags & SY_SUBSCRIPTED ) {
            item_size *= sym->ns.si.va.dim_ext->num_elts;
        }
        if( item_size > MaxSegSize ) {
            p_type = TY_HUGE_POINTER;
        } else if( item_size <= DataThreshold ) {
            p_type = TY_LOCAL_POINTER;
        } else {
            p_type = TY_GLOBAL_POINTER;
        }
    } else {
        p_type = TY_LOCAL_POINTER;
    }
    return( p_type );
}