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, ¬_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 ); }
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 ); }
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 ); }