void SegmentCgInit( // INITIALIZE SEGMENTS FOR CODE-GENERATION void ) { PC_SEGMENT *segment; // - current segment RingIterBeg( seg_list, segment ) { switch( segment->seg_id ) { case SEG_STACK : // Cg already "knows" about this segment segment->cg_defed = TRUE; break; default : if( segment->attrs & BACK ) { segmentCgDefine( segment ); break; } if( ! segment->used ) break; // drops thru case SEG_DATA : case SEG_CONST : case SEG_CONST2 : case SEG_BSS : // These could be defined only if they are used but unfortunately // the CG doesn't like DGROUP segments being defined on the fly. // Based pointers would cause these segments to be defined on the // fly so if we get rid of based pointer support, we could selectively // define them but then again, it's only four segments... segmentCgDefine( segment ); break; } } RingIterEnd( segment ) flags.in_back_end = TRUE; }
static THROW_RO *throwRoGet( // GET THROW R/O BLOCK TYPE type ) // - type being thrown { THROW_RO *srch; // - search R/O block for symbol THROW_RO *ro; // - R/O block for symbol SYMBOL sym; // - symbol for throw object THROW_CNV_CTL ctl; // - control area target_offset_t offset; // - offset ( not used ) type = TypeCanonicalThr( type ); ro = NULL; RingIterBeg( ring_throw_ro, srch ) { if( TypesIdentical( srch->sig->type, type ) ) { ro = srch; break; } } RingIterEnd( srch ); if( ro == NULL ) { ro = RingCarveAlloc( carveTHROW_RO, &ring_throw_ro ); ro->sig = BeTypeSignature( type ); ro->emitted = false; sym = CgVarRo( CgbkInfo.size_offset + sizeOfThrowCnv() * ThrowCnvInit( &ctl, type ), SC_PUBLIC, CppNameThrowRo( type ) ); ro->sym = sym; for( ; ; ) { type = ThrowCnvType( &ctl, &offset ); if( type == NULL ) break; BeTypeSignature( type ); } ThrowCnvFini( &ctl ); } return( ro ); }
static void writeExtrefs( void ) { unsigned len; PRAG_EXT_REF *e; RingIterBeg( pragmaExtrefs, e ) { if( e->symbol != NULL ) { SymbolPCHWrite( e->symbol ); } } RingIterEnd( e ) PCHWriteCVIndexTerm(); RingIterBeg( pragmaExtrefs, e ) { if( e->symbol == NULL ) { len = strlen( e->name ); PCHWriteUInt( len ); PCHWrite( e->name, len + 1 ); } } RingIterEnd( e ) PCHWriteUInt( 0 ); }
void PragmaExtrefsInject // INJECT EXTREFS FOR PRAGMAS ( void ) { PRAG_EXT_REF* entry; // - current entry RingIterBeg( pragmaExtrefs, entry ) { if( entry->symbol != NULL ) { CgInfoAddPragmaExtrefS( entry->symbol ); } else { CgInfoAddPragmaExtrefN( entry->name ); } } RingIterEnd( entry ); }
static ACTBLK* findActiveScope // FIND ACTIVE SCOPE ENTRY ( SCOPE scope ) // - the scope { ACTBLK* retn; // - entry for scope ACTBLK* curr; // - search entry retn = NULL; RingIterBeg( ring_active_blks, curr ) { if( scope == curr->scope ) { retn = curr; break; } } RingIterEnd( curr ); return retn; }
static PC_SEGMENT *segNameLookup( // LOOKUP SEGMENT FOR NAME char *name ) // - segment name { PC_SEGMENT* curr; // - current segment PC_SEGMENT* retn; // - segment for id retn = NULL; RingIterBeg( seg_list, curr ) { if( 0 == strcmp( curr->name, name ) ) { retn = curr; break; } } RingIterEnd( curr ); return retn; }
static PC_SEGMENT *segIdLookup( // LOOKUP SEGMENT FOR ID fe_seg_id seg_id ) // - segment id { PC_SEGMENT* curr; // - current segment PC_SEGMENT* retn; // - segment for id retn = NULL; RingIterBeg( seg_list, curr ) { if( curr->seg_id == seg_id ) { retn = curr; break; } } RingIterEnd( curr ); return retn; }
REPO_REC_FUN* RepoFunRead( // GET FUNCTION RECORD FROM REPOSITORY const char* name ) // - function name { REPO_REC_FUN* curr; // - current entry REPO_REC_FUN* retn; // - entry for function retn = NULL; RingIterBeg( funRepository, curr ) { if( 0 == strcmp( name, curr->name ) ) { retn = curr; break; } } RingIterEnd( curr ); return retn; }
static VFTGEN* findVftGen( // LOCATE VFTGEN FOR SYMBOL SYMBOL vft ) // - VFT symbol { VFTGEN* retn; // - entry to be returned VFTGEN* curr; // - current entry retn = NULL; RingIterBeg( vfts, curr ) { if( curr->sym == vft ) { retn = curr; break; } } RingIterEnd( curr ); return retn; }
void SegmentCodeCgInit( // TURN OFF USED BIT FOR ALL CODE SEGMENTS void ) { PC_SEGMENT *segment; // - current segment // reset any #pragma data_seg/code_seg changes back to defaults SegmentData( NULL, NULL ); SegmentCode( NULL, NULL ); RingIterBeg( seg_list, segment ) { if( ( segment->attrs & EXEC ) && ! segment->has_data ) { _markUsed( segment, FALSE ); } } RingIterEnd( segment ) // call out for non-call graph code segment uses DbgSuppSegRequest(); // used for default code segment externs SegmentMarkUsed( SEG_CODE ); }
static void processCdtor( // PROCESS A CDTOR ENTRY IF POSSIBLE call_handle handle, // - handle for call boolean direct ) // - TRUE ==> direct call { cdtor_entry* curr; // - current entry cdtor_entry* prev; // - previous entry prev = NULL; RingIterBeg( ring_cdtors, curr ) { if( curr->handle == handle ) { if( direct ) { CallStabCdArgSet( handle, curr->value ); } RingPruneWithPrev( &ring_cdtors, curr, prev ); CarveFree( carver_cdtors, curr ); break; } prev = curr; } RingIterEnd( curr ); }
static void brinfMacFini // COMPLETION ( INITFINI* defn ) // - definition { defn = defn; if( 0 != carveMacVals ) { MACVALUE* curr; RingIterBeg( values, curr ) { switch( curr->type ) { case MVT_DEFINED : case MVT_UNDEFED : { void* temp = curr->defin; curr->defin = NULL; CMemFree( temp ); // same format for undef'ed } break; } } RingIterEnd( curr ); CarveDestroy( carveMacVals ); carveMacVals = 0; VstkClose( &undefs ); }
void PragmaExtrefsValidate // VALIDATE EXTREFS FOR PRAGMAS ( void ) { PRAG_EXT_REF* entry; // - current entry RingIterBeg( pragmaExtrefs, entry ) { if( entry->symbol != NULL ) { SYMBOL symbol = entry->symbol; if( SymIsExtern( symbol ) ) { if( IsOverloadedFunc( symbol ) ) { CErr2p( ERR_PRAG_EXTREF_OVERLOADED, symbol ); entry->symbol = NULL; } } else { CErr2p( ERR_PRAG_EXTREF_EXTERN, symbol ); entry->symbol = NULL; } } } RingIterEnd( entry ); }
void ThrowRoGen( // GENERATE A THROW R/O BLOCK void ) { THROW_RO *ro; // - R/O block for symbol segment_id old_seg; // - old segment TYPE type; // - type being converted THROW_CNV_CTL ctl; // - control for conversions target_offset_t offset; // - offset within class RingIterBeg( ring_throw_ro, ro ) { if( ! ro->emitted ) { ro->emitted = true; old_seg = DgSetSegSym( ro->sym ); CgBackGenLabelInternal( ro->sym ); offset = ThrowCnvInit( &ctl, ro->sig->type ); DbgVerify( ! ctl.error_occurred , "cgGenThrowRo -- failure in ThrowCnvInit" ); #ifndef NDEBUG if( PragDbgToggle.dump_stab ) { printf( "ThrowRo[%p] offset=%p sig=%x\n" , ro , ro->sig , offset ); } #endif DgOffset( offset ); for( ; ; ) { type = ThrowCnvType( &ctl, &offset ); if( type == NULL ) break; cgGenThrowCnv( type, offset ); } ThrowCnvFini( &ctl ); BESetSeg( old_seg ); } } RingIterEnd( ro ); }
bool StabGenerate( // GENERATE A STATE TABLE STAB_CTL* sctl ) // - state-table information { STAB_DEFN* defn; // - state-table definition SE* se; // - current state entry SE* state_table; // - the state table segment_id old_seg; // - old segment if( sctl->rw == NULL ) return FALSE; defn = sctl->defn; old_seg = DgSetSegSym( defn->ro ); CgBackGenLabelInternal( defn->ro ); DgOffset( defn->kind ); #if _CPU == _AXP if( defn->kind == DTRG_FUN ) { DgOffset( - CgOffsetRw( 0 ) ); } #endif state_table = defn->state_table; RingIterBeg( state_table, se ) { if( se->base.gen ) { switch( se->base.se_type ) { case DTC_SYM_AUTO : DbgVerify( UNDEF_AREL != se->sym_auto.offset, "cgStateTable -- no offset for SYM_AUTO" ); DgPtrSymCode( se->sym_auto.dtor ); DgOffset( CgOffsetRw( se->sym_auto.offset ) ); padOffsetToPtrSize(); break; case DTC_SYM_STATIC : DgPtrSymCode( se->sym_static.dtor ); DgPtrSymData( se->sym_static.sym ); break; case DTC_TEST_FLAG : cgStateTableCmd( CgCmdTestFlag( se ), 0 ); break; case DTC_TRY : se->try_blk.sym = cgStateTableCmd( CgCmdTry( se ), 0 ); break; case DTC_CATCH : cgStateTableCmd( se->catch_blk.try_blk->try_blk.sym, sizeof( DTOR_CMD_CODE ) ); break; case DTC_FN_EXC : cgStateTableCmd( CgCmdFnExc( se ), 0 ); break; case DTC_SET_SV : if( se != state_table ) { cgStateTableCmd( CgCmdSetSv( se ), 0 ); } break; case DTC_ACTUAL_DBASE : case DTC_ACTUAL_VBASE : case DTC_COMP_VBASE : case DTC_COMP_DBASE : case DTC_COMP_MEMB : cgStateTableCmd( CgCmdComponent( se ), 0 ); break; case DTC_ARRAY_INIT : cgStateTableCmd( CgCmdArrayInit( se ), 0 ); break; case DTC_DLT_1 : cgStateTableCmd( CgCmdDlt1( se ), 0 ); break; case DTC_DLT_2 : cgStateTableCmd( CgCmdDlt2( se ), 0 ); break; case DTC_DLT_1_ARRAY : cgStateTableCmd( CgCmdDlt1Array( se ), 0 ); break; case DTC_DLT_2_ARRAY : cgStateTableCmd( CgCmdDlt2Array( se ), 0 ); break; case DTC_CTOR_TEST : cgStateTableCmd( CgCmdCtorTest( se ), 0 ); break; DbgDefault( "cgStateTable -- impossible" ); } } } RingIterEnd( se ) #if !defined( NDEBUG ) || !defined( _INTEL_CPU ) DgPtrSymCode( NULL ); DgPtrSymData( NULL ); #endif BESetSeg( old_seg ); StabDefnFreeStateTable( defn ); return TRUE; }
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 ); }