static unsigned cg_defined_type( // GET DEFINED TYPE TYPE type, // - C++ type CGREFNO *refno ) // - addr( reference # for type ) { CGREFNO retn; // - returned type retn = *refno; if( retn == NULL_CGREFNO ) { retn = cg_new_type( CgMemorySize( type ), CgMemorySize( AlignmentType( type ) ) ); *refno = retn; } return( retn ); }
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; }
PTREE NodeConvertVirtualPtr( // EXECUTE A VIRTUAL BASE CAST PTREE expr, // - expr to cast TYPE final_type, // - final type after cast target_offset_t vb_offset, // - offset of vbptr vindex vb_index ) // - index in vbtable { PTREE offset; TYPE vbptr_type; TYPE adjust_type; PTREE dup; vbptr_type = MakeVBTableFieldType( true ); offset = NodeOffset( vb_offset ); expr = NodeBinary( CO_DOT, expr, offset ); expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr->type = vbptr_type; dup = NodeDupExpr( &expr ); expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr = NodeFetch( expr ); expr->type = vbptr_type; expr->flags &= ~ PTF_LVALUE; expr->flags |= PTF_PTR_NONZERO; adjust_type = TypePointedAtModified( vbptr_type ); offset = NodeOffset( vb_index * CgMemorySize( adjust_type ) ); expr = NodeBinary( CO_DOT, expr, offset ); expr->type = adjust_type; expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr = NodeFetch( expr ); expr->type = adjust_type; expr->flags |= PTF_PTR_NONZERO; expr = NodeBinary( CO_DOT, dup, expr ); expr->type = final_type; expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; return( expr ); }
static void dumpMember( // DUMP A MEMBER SYMBOL memb, // - member void *_di ) // - dump information { DUMP_INFO* di = _di; target_offset_t offset; // - offset of symbol TYPE type; // - type of symbol NAME name; // - symbol's name offset = di->offset + memb->u.member_offset; name = memb->name->name; type = TypedefModifierRemove( memb->sym_type ); if( type->id == TYP_BITFIELD ) { di = dumpBitMemb( di , "bit member:" , NameStr( name ) , offset , type->u.b.field_start , type->u.b.field_width ); } else { di = dumpDataMemb( di , "member:" , NameStr( name ) , offset , CgMemorySize( type ) ); } }
static PTREE genVfunCall( // DIRECTLY GENERATE VFUN CALL target_offset_t vf_offset, // - offset to VF table ptr PTREE node, // - original "this" expression target_offset_t vf_index, // - index into VF table SYMBOL sym ) // - symbol to access { TYPE vfptr_type; // - type[ ptr to VF table ] TYPE vfn_type; // - type[ ptr to VF ] node = NodeBinary( CO_DOT, node, NodeOffset( vf_offset ) ); vfptr_type = MakeVFTableFieldType( TRUE ); node->type = vfptr_type; node->flags |= PTF_LVALUE; node = PtdExprConst( node ); node = NodeRvalue( node ); vfn_type = TypePointedAtModified( vfptr_type ); node = NodeBinary( CO_DOT , node , NodeOffset( vf_index * CgMemorySize( vfn_type ) ) ); node->type = vfn_type; node->flags |= PTF_LVALUE; node = NodeRvalue( node ); node->type = sym->sym_type; return node; }
static target_size_t segmentTypeSize( // SEGMENT: SIZE OF TYPE TYPE type ) // - type to be sized { target_size_t size; size = CgMemorySize( type ); if( size == 0 ) { size = TARGET_CHAR; } return( size ); }
void DgSymbolDefInit( // DATA GENERATE SYMBOL (DEFAULT DATA) SYMBOL sym ) // - the symbol { segment_id old_seg; // - old segment segment_id seg_id; // - symbol segment target_size_t size; // - size of symbol seg_id = FESegID( sym ); old_seg = BESetSeg( seg_id ); DgAlignSegment( seg_id, SegmentAlignment( sym->sym_type ) ); CgBackGenLabel( sym ); size = CgMemorySize( sym->sym_type ); if( sym->segid == SEG_BSS ) { DgUninitBytes( size ); } else { DgInitBytes( size, 0 ); } BESetSeg( old_seg ); }
static fe_seg_id cgSegIdBased( SYMBOL sym, type_flag flags ) { fe_seg_id id; // - segment id target_offset_t align; // - alignment for symbol target_size_t size; // - size of symbol TYPE base_mod; // - __based modifier size = CgMemorySize( sym->sym_type ); #ifdef _CHECK_SIZE // only defined if needed if( !(flags & TF1_HUGE) ) { if( _CHECK_SIZE( size ) ) { CErr2p( ERR_DATA_TOO_BIG, sym ); return( SEG_NULL ); } } #endif if( SymIsExtern( sym ) ) { // not defined in this compilation unit id = SegmentImport(); } else { switch( flags & TF1_BASED ) { case TF1_BASED_STRING: id = SegmentFindBased( sym->sym_type ); break; case TF1_BASED_SELF: case TF1_BASED_VOID: id = SEG_NULL; break; case TF1_BASED_FETCH: case TF1_BASED_ADD: base_mod = BasedType( sym->sym_type ); id = CgSegIdData( (SYMBOL)base_mod->u.m.base, SI_DEFAULT ); break; DbgDefault( "invalid based cgsegid call" ); } if( id != SEG_NULL ) { align = cgSegIdAlign( sym, flags ); id = SegmentAddSym( sym, id, size, align ); } } return( id ); }
static fe_seg_id cgSegIdVariable( SYMBOL sym, type_flag flags, SEGID_CONTROL control ) { fe_seg_id id; target_size_t size; size = CgMemorySize( sym->sym_type ); #ifdef _CHECK_SIZE // only defined if needed if( !(flags & TF1_HUGE) ) { if( _CHECK_SIZE( size ) ) { CErr2p( ERR_DATA_TOO_BIG, sym ); return( SEG_NULL ); } } #endif if( flags & TF1_NEAR ) { id = cgSegIdNearVariable( sym, flags, size, control ); } else if( flags & TF1_HUGE ) { id = cgSegIdHugeVariable( sym, flags, size, control ); } else if( flags & TF1_FAR ) { id = cgSegIdFarVariable( sym, flags, size, control ); } else { boolean assume_near = TRUE; if( IsBigData() ) { if( flags & TF1_DEFAULT_FAR ) { assume_near = FALSE; } else if( size == 0 || size > DataThreshold ) { assume_near = FALSE; } else if( CompFlags.zc_switch_used ) { if( cgSegIdConst( sym, flags, control ) ) { // symbol may have been placed in code segment assume_near = FALSE; } } } if( assume_near ) { id = cgSegIdNearVariable( sym, flags, size, control ); } else { id = cgSegIdFarVariable( sym, flags, size, control ); } } return( id ); }
static fe_seg_id cgSegIdThread( SYMBOL sym, type_flag flags ) { fe_seg_id id; // - segment id flags = flags; #ifdef _CHECK_SIZE // only defined if needed if( !(flags & TF1_HUGE) ) { target_size_t size; // - size of symbol size = CgMemorySize( sym->sym_type ); if( _CHECK_SIZE( size ) ) { CErr2p( ERR_DATA_TOO_BIG, sym ); return( SEG_NULL ); } } #endif if( SymIsExtern( sym ) ) { // not defined in this compilation unit id = SegmentImport(); } else { id = SEG_TLS; } return( id ); }
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 ); }
void DumpObjectModelEnum( // DUMP OBJECT MODEL: ENUM TYPE type ) // - enum type { SYMBOL sym; // - current symbol TYPE base; // - base type VBUF buffer; // - printing buffer char buf[16]; // - buffer int numb; // - a numeric value const char *name; // - name to be printed bool sign; // - TRUE ==> signed enum unsigned mask; // - used to mask to true size unsigned val; // - value as unsigned CompFlags.log_note_msgs = TRUE; base = TypedefModifierRemoveOnly( type ); sym = base->u.t.sym; VbufInit( &buffer ); VbufConcStr( &buffer, "Object Model for: " ); if( NULL == sym->name->name || NameStr( sym->name->name )[0] == '.' ) { VbufConcStr( &buffer, "anonymous enum type" ); } else { VbufConcStr( &buffer, NameStr( sym->name->name ) ); } switch( TypedefModifierRemove( base->of ) -> id ) { case TYP_CHAR : case TYP_UCHAR : name = "unsigned char"; sign = FALSE; break; case TYP_SCHAR : name = "signed char"; sign = TRUE; break; case TYP_SSHORT : name = "signed short"; sign = TRUE; break; case TYP_USHORT : name = "unsigned short"; sign = FALSE; break; case TYP_SINT : name = "signed int"; sign = TRUE; break; case TYP_UINT : name = "unsigned int"; sign = FALSE; break; case TYP_SLONG : name = "signed long"; sign = TRUE; break; case TYP_ULONG : name = "unsigned long"; sign = FALSE; break; case TYP_SLONG64 : name = "__int64"; sign = TRUE; break; case TYP_ULONG64 : name = "unsigned __int64"; sign = FALSE; break; DbgDefault( "DumpObjectModelEnum -- bad underlying type" ); } VbufConcStr( &buffer, ", base type is " ); VbufConcStr( &buffer, name ); vbufWrite( &buffer ); mask = CgMemorySize( base ); if( mask == sizeof( unsigned ) ) { mask = -1; } else { mask = ( 1 << ( mask * 8 ) ) - 1; } for( ; ; ) { sym = sym->thread; if( ! SymIsEnumeration( sym ) ) break; VbufRewind( &buffer ); VbufConcStr( &buffer, " " ); VbufConcStr( &buffer, NameStr( sym->name->name ) ); VbufConcStr( &buffer, " = " ); numb = sym->u.sval; if( sign && numb < 0 ) { VbufConcChr( &buffer, '-' ); VbufConcDecimal( &buffer, -numb ); } else { VbufConcDecimal( &buffer, numb ); } val = mask & numb; if( val > 10 ) { itoa( val, buf, 16 ); VbufConcStr( &buffer, " /0x" ); VbufConcStr( &buffer, buf ); } vbufWrite( &buffer ); } VbufFree( &buffer ); CompFlags.log_note_msgs = FALSE; }
static PTREE transformVaStart // TRANSFORM TO CO_VASTART OPCODE ( PTREE expr ) // - va_start expression { SYMBOL pre_ellipsis_sym; SYMBOL stop; SYMBOL curr; SYMBOL fn; SCOPE caller_arg_scope; unsigned offset; target_size_t arg_size; PTREE arg1; PTREE arg2; PTREE arg3; PTREE valist; // second argument -- must be pre-... parameter arg1 = expr->u.subtree[1]; arg2 = arg1->u.subtree[0]; arg3 = arg2->u.subtree[0]; pre_ellipsis_sym = PTreeOp( &arg2->u.subtree[1] )->u.symcg.symbol; caller_arg_scope = ScopeFunctionScopeInProgress(); fn = ScopeFunction( caller_arg_scope ); offset = 0; if( ObjModelFunctionReturn( fn->sym_type ) == OMR_CLASS_VAL ) { offset += TARGET_PACKING; } if( SymIsThisMember( fn ) ) { offset += TARGET_PACKING; if( SymCDtorExtraParm( fn ) ) { offset += TARGET_PACKING; } } stop = ScopeOrderedStart( caller_arg_scope ); curr = NULL; for(;;) { curr = ScopeOrderedNext( stop, curr ); if( curr == NULL ) { PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL ); return( expr ); } if( ObjModelArgument( curr->sym_type ) == OMR_CLASS_REF ) { arg_size = TARGET_PACKING; } else { arg_size = CgMemorySize( curr->sym_type ); arg_size += TARGET_PACKING - 1; arg_size &= ~( TARGET_PACKING - 1 ); } offset += arg_size; if( curr == pre_ellipsis_sym ) break; } if( ScopeOrderedNext( stop, curr ) != NULL ) { PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL ); return( expr ); } // third argument -- va_list symbol valist = arg1->u.subtree[1]; arg1->u.subtree[1] = NULL; if( arg3->u.subtree[1]->u.int_constant == 0 ) { // compensate for "void *__alist;" arg in <varargs.h> offset -= TARGET_PACKING; } NodeFreeDupedExpr( expr ); expr = NodeBinary( CO_VASTART, valist, NodeOffset( offset ) ); return expr; }