Example #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 );
}
Example #2
0
TYPE_SIG *TypeSigFind(          // FIND TYPE SIGNATURE
    TYPE_SIG_ACCESS acc,        // - access type
    TYPE type,                  // - type for signature
    TOKEN_LOCN* err_locn,       // - error location for access errors
    bool *error_occurred )      // - to set error indication
{
    TYPE_SIG *srch;             // - signature for searching
    TYPE_SIG *sig;              // - signature
    SYMBOL sym;                 // - symbol
    unsigned size;              // - size of R/O data
    NAME typesig_name;          // - name of type signature
    TYPE typesig_type;          // - type of type signature
    bool err_this_time;         // - true ==> we have error
    TYPE_SIG_ACCESS acc_ind;    // - indirect access

    err_this_time = false;
    type = TypeCanonicalThr( type );
    sig = NULL;
    RingIterBeg( type_sigs, srch ) {
        if( TypesSameExclude( srch->type, type, TC1_NOT_ENUM_CHAR ) ) {
            sig = srch;
            break;
        }
    } RingIterEnd( srch );
    if( sig == NULL ) {
        THROBJ thr;             // - category of object
        DbgVerify( 0 == ( acc & TSA_GEN )
                 , "TypeSigFind -- no type signature & TSA_GEN" );
        sig = RingCarveAlloc( carveTYPE_SIG, &type_sigs );
        sig->type = type;
        sig->default_ctor = NULL;
        sig->copy_ctor = NULL;
        sig->dtor = NULL;
        sig->sym = NULL;
        sig->base = NULL;
        sig->cgref = false;
        sig->cggen = false;
        sig->free = false;
        thr = ThrowCategory( type );
        if( acc & TSA_INDIRECT ) {
            acc_ind = acc | TSA_INDIRECT_ACCESS;
        } else if( acc & TSA_INDIRECT_ACCESS ) {
            acc_ind = ( acc & ~ TSA_INDIRECT ) | TSA_INDIRECT_GEN;
        } else {
            acc_ind = acc;
        }
        size = 0;
        switch( thr ) {
        case THROBJ_PTR_SCALAR :
        case THROBJ_PTR_CLASS :
            sig->base = TypeSigFind( acc_ind & TSA_INDIRECT
                                   , TypePointedAtModified( type )
                                   , err_locn
                                   , &err_this_time );
            size = typeSigHdrSize();
            break;
        case THROBJ_SCALAR :
        case THROBJ_PTR_FUN :
        case THROBJ_VOID_STAR :
            size = typeSigHdrSize() + SizeTargetSizeT();
            break;
        case THROBJ_REFERENCE :
            sig->base = TypeSigFind( acc_ind
                                   , TypeReference( type )
                                   , err_locn
                                   , &err_this_time );
            break;
        case THROBJ_CLASS :
        case THROBJ_CLASS_VIRT :
            size = 3 * CgCodePtrSize() + CgDataPtrSize() + typeSigHdrSize();
            break;
        case THROBJ_ANYTHING :
            break;
        default :
            DbgStmt( CFatal( "cgTypeSignature -- invalid throw category" ) );
        }
        size += typeSigNameSize( thr );
        if( size == 0 ) {
            sym = NULL;
        } else {                // - type for TYPE SIGNATURE variable
            typesig_name = CppNameTypeSig( type );
            sym = ScopeAlreadyExists( GetFileScope(), typesig_name );
            if( sym == NULL ) {
                typesig_type = MakeInternalType( size );
                typesig_type = MakeCompilerConstCommonData( typesig_type );
                sym = SymCreateFileScope( typesig_type
                                        , SC_PUBLIC
                                        , SF_REFERENCED | SF_ADDR_TAKEN
                                        , typesig_name );
                LinkageSet( sym, "C++" );
                CgSegId( sym );
            }
        }
        sig->sym = sym;
    }
    if( err_this_time ) {
        *error_occurred = true;
    } else {
        if( NULL != sig->sym ) {
            SegmentMarkUsed( sig->sym->segid );
        }
        *error_occurred = false;
        typeSigAccess( acc, sig, err_locn, error_occurred );
    }
    return( sig );
}
Example #3
0
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 );
}