diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/IroVars.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-main.tar.gz MWCC-main.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/IroVars.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroVars.c | 1430 |
1 files changed, 0 insertions, 1430 deletions
diff --git a/compiler_and_linker/unsorted/IroVars.c b/compiler_and_linker/unsorted/IroVars.c deleted file mode 100644 index 6bb3d02..0000000 --- a/compiler_and_linker/unsorted/IroVars.c +++ /dev/null @@ -1,1430 +0,0 @@ -#include "compiler/IroVars.h" -#include "compiler/IroDump.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroJump.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroMalloc.h" -#include "compiler/IroPointerAnalysis.h" -#include "compiler/IroUtil.h" -#include "compiler/IROUseDef.h" -#include "compiler/CClass.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CParser.h" -#include "compiler/CompilerTools.h" -#include "compiler/Exceptions.h" -#include "compiler/objects.h" -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/BitVector.h" - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct IndirectRecordMatch { - IROLinear *nd; - struct IndirectRecordMatch *otherMatches; -} IndirectRecordMatch; - -typedef struct IndirectRecord { - IROLinear *linear; - unsigned char flags; - VarRecord *var; - SInt32 addend; - SInt32 size; - int startbit; - int endbit; - Type *type; - struct IndirectRecord *next; - IndirectRecordMatch *matches; - IROLinear *x26; -} IndirectRecord; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -static IndirectRecord *IRO_FirstIndirectRecord; -static IndirectRecord *IRO_LastIndirectRecord; -static IROLinear *TheBaseTerm; -VarRecord *IRO_FirstVar; -VarRecord *IRO_LastVar; -SInt32 IRO_NumVars; -Boolean IRO_IsBitField; -SInt32 IRO_BaseTerms; -SInt32 IRO_VarTerms; -Boolean IRO_IsModifyOp[MAXEXPR]; -Boolean IRO_IsAssignOp[MAXEXPR]; - -// forward decls -static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag); -static Boolean CheckAddressConsistency(IROLinear *nd, VarRecord *var, SInt32 addend, Type *type); -static void DisableEntries(IndirectRecord *irec); -static void DisableAddressedEntries(void); -static UInt32 ObjectIsArg(Object *obj); - -void IRO_InitializeIRO_IsModifyOpArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - IRO_IsModifyOp[i] = 0; - - IRO_IsModifyOp[EPOSTINC] = 1; - IRO_IsModifyOp[EPOSTDEC] = 1; - IRO_IsModifyOp[EPREINC] = 1; - IRO_IsModifyOp[EPREDEC] = 1; - IRO_IsModifyOp[EINDIRECT] = 0; - IRO_IsModifyOp[EMONMIN] = 0; - IRO_IsModifyOp[EBINNOT] = 0; - IRO_IsModifyOp[ELOGNOT] = 0; - IRO_IsModifyOp[EFORCELOAD] = 0; - IRO_IsModifyOp[EMUL] = 0; - IRO_IsModifyOp[EMULV] = 0; - IRO_IsModifyOp[EDIV] = 0; - IRO_IsModifyOp[EMODULO] = 0; - IRO_IsModifyOp[EADDV] = 0; - IRO_IsModifyOp[ESUBV] = 0; - IRO_IsModifyOp[EADD] = 0; - IRO_IsModifyOp[ESUB] = 0; - IRO_IsModifyOp[ESHL] = 0; - IRO_IsModifyOp[ESHR] = 0; - IRO_IsModifyOp[ELESS] = 0; - IRO_IsModifyOp[EGREATER] = 0; - IRO_IsModifyOp[ELESSEQU] = 0; - IRO_IsModifyOp[EGREATEREQU] = 0; - IRO_IsModifyOp[EEQU] = 0; - IRO_IsModifyOp[ENOTEQU] = 0; - IRO_IsModifyOp[EAND] = 0; - IRO_IsModifyOp[EXOR] = 0; - IRO_IsModifyOp[EOR] = 0; - IRO_IsModifyOp[ELAND] = 0; - IRO_IsModifyOp[ELOR] = 0; - IRO_IsModifyOp[EASS] = 0; - IRO_IsModifyOp[EMULASS] = 1; - IRO_IsModifyOp[EDIVASS] = 1; - IRO_IsModifyOp[EMODASS] = 1; - IRO_IsModifyOp[EADDASS] = 1; - IRO_IsModifyOp[ESUBASS] = 1; - IRO_IsModifyOp[ESHLASS] = 1; - IRO_IsModifyOp[ESHRASS] = 1; - IRO_IsModifyOp[EANDASS] = 1; - IRO_IsModifyOp[EXORASS] = 1; - IRO_IsModifyOp[EORASS] = 1; - IRO_IsModifyOp[ECOMMA] = 0; - IRO_IsModifyOp[EPMODULO] = 1; - IRO_IsModifyOp[EROTL] = 1; - IRO_IsModifyOp[EROTR] = 1; - IRO_IsModifyOp[EBCLR] = 1; - IRO_IsModifyOp[EBTST] = 1; - IRO_IsModifyOp[EBSET] = 1; - IRO_IsModifyOp[ETYPCON] = 0; - IRO_IsModifyOp[EBITFIELD] = 0; - IRO_IsModifyOp[EINTCONST] = 0; - IRO_IsModifyOp[EFLOATCONST] = 0; - IRO_IsModifyOp[ESTRINGCONST] = 0; - IRO_IsModifyOp[ECOND] = 0; - IRO_IsModifyOp[EFUNCCALL] = 0; - IRO_IsModifyOp[EFUNCCALLP] = 0; - IRO_IsModifyOp[EOBJREF] = 0; - IRO_IsModifyOp[EMFPOINTER] = 0; - IRO_IsModifyOp[ENULLCHECK] = 0; - IRO_IsModifyOp[EPRECOMP] = 0; - IRO_IsModifyOp[ETEMP] = 0; - IRO_IsModifyOp[EARGOBJ] = 0; - IRO_IsModifyOp[ELOCOBJ] = 0; - IRO_IsModifyOp[ELABEL] = 0; - IRO_IsModifyOp[ESETCONST] = 0; - IRO_IsModifyOp[ENEWEXCEPTION] = 0; - IRO_IsModifyOp[ENEWEXCEPTIONARRAY] = 0; - IRO_IsModifyOp[EOBJLIST] = 0; - IRO_IsModifyOp[EMEMBER] = 0; - IRO_IsModifyOp[ETEMPLDEP] = 0; - IRO_IsModifyOp[EINSTRUCTION] = 0; - IRO_IsModifyOp[EDEFINE] = 0; - IRO_IsModifyOp[EREUSE] = 0; - IRO_IsModifyOp[EASSBLK] = 0; - IRO_IsModifyOp[EVECTOR128CONST] = 0; - IRO_IsModifyOp[ECONDASS] = 1; -} - -void IRO_InitializeIRO_IsAssignOpArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - IRO_IsAssignOp[i] = 0; - - IRO_IsAssignOp[EPOSTINC] = 1; - IRO_IsAssignOp[EPOSTDEC] = 1; - IRO_IsAssignOp[EPREINC] = 1; - IRO_IsAssignOp[EPREDEC] = 1; - IRO_IsAssignOp[EINDIRECT] = 0; - IRO_IsAssignOp[EMONMIN] = 0; - IRO_IsAssignOp[EBINNOT] = 0; - IRO_IsAssignOp[ELOGNOT] = 0; - IRO_IsAssignOp[EFORCELOAD] = 0; - IRO_IsAssignOp[EMUL] = 0; - IRO_IsAssignOp[EMULV] = 0; - IRO_IsAssignOp[EDIV] = 0; - IRO_IsAssignOp[EMODULO] = 0; - IRO_IsAssignOp[EADDV] = 0; - IRO_IsAssignOp[ESUBV] = 0; - IRO_IsAssignOp[EADD] = 0; - IRO_IsAssignOp[ESUB] = 0; - IRO_IsAssignOp[ESHL] = 0; - IRO_IsAssignOp[ESHR] = 0; - IRO_IsAssignOp[ELESS] = 0; - IRO_IsAssignOp[EGREATER] = 0; - IRO_IsAssignOp[ELESSEQU] = 0; - IRO_IsAssignOp[EGREATEREQU] = 0; - IRO_IsAssignOp[EEQU] = 0; - IRO_IsAssignOp[ENOTEQU] = 0; - IRO_IsAssignOp[EAND] = 0; - IRO_IsAssignOp[EXOR] = 0; - IRO_IsAssignOp[EOR] = 0; - IRO_IsAssignOp[ELAND] = 0; - IRO_IsAssignOp[ELOR] = 0; - IRO_IsAssignOp[EASS] = 1; - IRO_IsAssignOp[EMULASS] = 1; - IRO_IsAssignOp[EDIVASS] = 1; - IRO_IsAssignOp[EMODASS] = 1; - IRO_IsAssignOp[EADDASS] = 1; - IRO_IsAssignOp[ESUBASS] = 1; - IRO_IsAssignOp[ESHLASS] = 1; - IRO_IsAssignOp[ESHRASS] = 1; - IRO_IsAssignOp[EANDASS] = 1; - IRO_IsAssignOp[EXORASS] = 1; - IRO_IsAssignOp[EORASS] = 1; - IRO_IsAssignOp[ECOMMA] = 0; - IRO_IsAssignOp[EPMODULO] = 1; - IRO_IsAssignOp[EROTL] = 1; - IRO_IsAssignOp[EROTR] = 1; - IRO_IsAssignOp[EBCLR] = 1; - IRO_IsAssignOp[EBTST] = 1; - IRO_IsAssignOp[EBSET] = 1; - IRO_IsAssignOp[ETYPCON] = 0; - IRO_IsAssignOp[EBITFIELD] = 0; - IRO_IsAssignOp[EINTCONST] = 0; - IRO_IsAssignOp[EFLOATCONST] = 0; - IRO_IsAssignOp[ESTRINGCONST] = 0; - IRO_IsAssignOp[ECOND] = 0; - IRO_IsAssignOp[EFUNCCALL] = 0; - IRO_IsAssignOp[EFUNCCALLP] = 0; - IRO_IsAssignOp[EOBJREF] = 0; - IRO_IsAssignOp[EMFPOINTER] = 0; - IRO_IsAssignOp[ENULLCHECK] = 0; - IRO_IsAssignOp[EPRECOMP] = 0; - IRO_IsAssignOp[ETEMP] = 0; - IRO_IsAssignOp[EARGOBJ] = 0; - IRO_IsAssignOp[ELOCOBJ] = 0; - IRO_IsAssignOp[ELABEL] = 0; - IRO_IsAssignOp[ESETCONST] = 0; - IRO_IsAssignOp[ENEWEXCEPTION] = 0; - IRO_IsAssignOp[ENEWEXCEPTIONARRAY] = 0; - IRO_IsAssignOp[EOBJLIST] = 0; - IRO_IsAssignOp[EMEMBER] = 0; - IRO_IsAssignOp[ETEMPLDEP] = 0; - IRO_IsAssignOp[EINSTRUCTION] = 0; - IRO_IsAssignOp[EDEFINE] = 0; - IRO_IsAssignOp[EREUSE] = 0; - IRO_IsAssignOp[EASSBLK] = 0; - IRO_IsAssignOp[EVECTOR128CONST] = 0; - IRO_IsAssignOp[ECONDASS] = 1; -} - -VarRecord *IRO_FindVar(Object *object, Boolean flag1, Boolean flag2) { - VarRecord *var; - VarInfo *vi; - - var = object->varptr; - if (!var && flag1) { - vi = NULL; - if (object->datatype == DLOCAL) - vi = object->u.var.info; - if (vi) - vi->usage = 0; - var = oalloc(sizeof(VarRecord)); - var->object = object; - var->index = ++IRO_NumVars; - var->x6 = 0; - var->xA = 0; - var->next = NULL; - var->defs = NULL; - var->uses = NULL; - var->x1A = NULL; - var->x1E = NULL; - var->xB = 0; - if (IRO_FirstVar) - IRO_LastVar->next = var; - else - IRO_FirstVar = var; - IRO_LastVar = var; - object->varptr = var; - } - - if (var && !flag2) { - var->xB = 1; - if (object->datatype == DLOCAL && object->u.var.info && object->u.var.info->noregister == 0) - object->u.var.info->noregister = 2; - } - - return var; -} - -static void ResetVars(void) { - VarRecord *var; - - for (var = IRO_FirstVar; var; var = var->next) { - var->xB = 0; - if (var->object && var->object->datatype == DLOCAL && var->object->u.var.info) { - if (var->object->u.var.info->noregister == 2) - var->object->u.var.info->noregister = 0; - } - } -} - -static void IRO_HandleExceptionActions(IROLinear *linear) { - ExceptionAction *action; - - for (action = linear->stmt->dobjstack; action; action = action->prev) { - switch (action->type) { - case EAT_DESTROYLOCAL: - IRO_FindVar(action->data.destroy_local.local, 1, 0); - break; - case EAT_DESTROYLOCALCOND: - IRO_FindVar(action->data.destroy_local_cond.local, 1, 0); - break; - case EAT_DESTROYLOCALOFFSET: - IRO_FindVar(action->data.destroy_local_offset.local, 1, 0); - break; - case EAT_DESTROYLOCALARRAY: - IRO_FindVar(action->data.destroy_local_array.localarray, 1, 0); - break; - case EAT_DESTROYMEMBER: - case EAT_DESTROYBASE: - IRO_FindVar(action->data.destroy_member.objectptr, 1, 0); - break; - case EAT_DESTROYMEMBERCOND: - IRO_FindVar(action->data.destroy_member_cond.objectptr, 1, 0); - break; - case EAT_DESTROYMEMBERARRAY: - IRO_FindVar(action->data.destroy_member_array.objectptr, 1, 0); - break; - case EAT_CATCHBLOCK: - if (action->data.catch_block.catch_object) - IRO_FindVar(action->data.catch_block.catch_object, 1, 0); - IRO_FindVar(action->data.catch_block.catch_info_object, 1, 0); - break; - case EAT_ACTIVECATCHBLOCK: - IRO_FindVar(action->data.active_catch_block.catch_info_object, 1, 0); - break; - } - } -} - -void IRO_FindAllVars(void) { - IROLinear *linear; - VarRecord *var; - - linear = IRO_FirstLinear; - IRO_NumVars = 0; - IRO_FirstVar = IRO_LastVar = NULL; - - while (linear) { - if (IS_LINEAR_ENODE(linear, EOBJREF)) { - if (Inline_IsObjectData(linear->u.node->data.objref) || linear->u.node->data.objref->datatype == DLOCAL) - IRO_FindVar(linear->u.node->data.objref, 1, (linear->flags & IROLF_Ind) != 0); - else - linear->u.node->data.objref->varptr = NULL; - } else if (linear->type == IROLinearFunccall) { - if (linear->stmt && IRO_FunctionCallMightThrowException(linear)) - IRO_HandleExceptionActions(linear); - } else if (linear->type == IROLinearAsm) { - IAEffects effects; - int i; - CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects); - for (i = 0; i < effects.numoperands; i++) - IRO_FindVar(effects.operands[i].object, 1, effects.operands[i].type != IAEffect_3); - } - linear = linear->next; - } - - var = IRO_FirstVar; - Bv_AllocVector(&IRO_FuncKills, IRO_NumVars + 1); - Bv_SetBit(0, IRO_FuncKills); - while (var) { - if (Inline_IsObjectData(var->object) || var->xB) - Bv_SetBit(var->index, IRO_FuncKills); - var = var->next; - } - - IRO_CheckForUserBreak(); -} - -void IRO_ZapVarPtrs(void) { - VarRecord *var; - - for (var = IRO_FirstVar; var; var = var->next) - var->object->varptr = NULL; -} - -void IRO_UpdateVars(void) { - IROLinear *linear; - VarRecord *var; - - ResetVars(); - - for (linear = IRO_FirstLinear; linear; linear = linear->next) { - if (IS_LINEAR_ENODE(linear, EOBJREF)) { - if (Inline_IsObjectData(linear->u.node->data.objref) || linear->u.node->data.objref->datatype == DLOCAL) - IRO_FindVar(linear->u.node->data.objref, 0, (linear->flags & IROLF_Ind) || !(linear->flags & IROLF_Reffed)); - } else if (linear->type == IROLinearFunccall) { - if (linear->stmt && IRO_FunctionCallMightThrowException(linear)) - IRO_HandleExceptionActions(linear); - } else if (linear->type == IROLinearAsm) { - IAEffects effects; - int i; - CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects); - for (i = 0; i < effects.numoperands; i++) - IRO_FindVar(effects.operands[i].object, 0, effects.operands[i].type != IAEffect_3); - } - } - - var = IRO_FirstVar; - Bv_AllocVector(&IRO_FuncKills, IRO_NumVars + 1); - Bv_SetBit(0, IRO_FuncKills); - while (var) { - if (Inline_IsObjectData(var->object) || var->xB) - Bv_SetBit(var->index, IRO_FuncKills); - var = var->next; - } -} - -void IRO_AddElmToList(IROLinear *linear, IROElmList **list) { - IROElmList *l = oalloc(sizeof(IROElmList)); - l->element = linear; - l->next = NULL; - if (!*list) { - *list = l; - } else { - l->next = *list; - *list = l; - } -} - -void IRO_DecomposeAddressExpression(IROLinear *linear, IROAddrRecord *rec) { - if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD)) { - IRO_DecomposeAddressExpression(linear->u.diadic.left, rec); - } else if (IS_LINEAR_ENODE(linear->u.diadic.left, EINTCONST)) { - rec->numInts++; - IRO_AddElmToList(linear->u.diadic.left, &rec->ints); - } else if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF)) { - rec->numObjRefs++; - IRO_AddElmToList(linear->u.diadic.left, &rec->objRefs); - } else { - rec->numMisc++; - IRO_AddElmToList(linear->u.diadic.left, &rec->misc); - } - - if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD)) { - IRO_DecomposeAddressExpression(linear->u.diadic.right, rec); - } else if (IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) { - rec->numInts++; - IRO_AddElmToList(linear->u.diadic.right, &rec->ints); - } else if (IS_LINEAR_ENODE(linear->u.diadic.right, EOBJREF)) { - rec->numObjRefs++; - IRO_AddElmToList(linear->u.diadic.right, &rec->objRefs); - } else { - rec->numMisc++; - IRO_AddElmToList(linear->u.diadic.right, &rec->misc); - } -} - -void IRO_DecomposeAddressExpression_Cheap(IROLinear *linear) { - if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD)) { - IRO_DecomposeAddressExpression_Cheap(linear->u.diadic.left); - } else if (!IS_LINEAR_ENODE(linear->u.diadic.left, EINTCONST)) { - if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF)) { - IRO_BaseTerms++; - TheBaseTerm = linear->u.diadic.left; - } else { - IRO_VarTerms++; - } - } - - if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD)) { - IRO_DecomposeAddressExpression_Cheap(linear->u.diadic.right); - } else if (!IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) { - if (IS_LINEAR_ENODE(linear->u.diadic.right, EOBJREF)) { - IRO_BaseTerms++; - TheBaseTerm = linear->u.diadic.right; - } else { - IRO_VarTerms++; - } - } -} - -VarRecord *IRO_FindAssigned(IROLinear *linear) { - VarRecord *rec; - - IRO_IsBitField = 0; - if (linear->type == IROLinearOp2Arg) - linear = linear->u.diadic.left; - else if (linear->type == IROLinearOp1Arg) - linear = linear->u.monadic; - else - CError_FATAL(818); - - if (IS_LINEAR_MONADIC(linear, EINDIRECT)) - linear = linear->u.monadic; - - if (IS_LINEAR_MONADIC(linear, EBITFIELD)) { - IRO_IsBitField = 1; - linear = linear->u.monadic; - } - - if (IS_LINEAR_DIADIC(linear, EADD)) { - if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF) && IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) { - linear = linear->u.diadic.left; - } else { - IRO_BaseTerms = 0; - IRO_DecomposeAddressExpression_Cheap(linear); - if (IRO_BaseTerms == 1) - linear = TheBaseTerm; - } - } - - if (!IS_LINEAR_ENODE(linear, EOBJREF)) - return NULL; - - if ((rec = IRO_FindVar(linear->u.node->data.objref, 0, 1))) - return rec; - else - return NULL; -} - -static void GetKillsByIndirectAssignment(IROLinear *linear) { - IROListNode *resultList; - IROLinear *nd; - IROListNode *list; - IROListNode *scan; - IROLinear *inner; - Boolean result; - Boolean foundLinear; - - result = 0; - - if (linear->type == IROLinearOp2Arg) - linear = linear->u.diadic.left; - else - linear = linear->u.monadic; - - if ( - linear && - linear->type == IROLinearOp1Arg && - linear->nodetype == EINDIRECT && - (inner = linear->u.monadic) && - copts.opt_pointer_analysis && - inner->pointsToFunction && - FunctionName - ) - { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 1; - break; - } - - foundLinear = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundLinear = 1; - break; - } - } - if (!foundLinear) { - result = 1; - break; - } - } - - if (!result) { - while (list) { - for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - Object *obj; - VarRecord *var; - int index; - - obj = nd->u.node->data.objref; - CError_ASSERT(952, obj != NULL); - - var = IRO_FindVar(obj, 1, 1); - CError_ASSERT(954, var != NULL); - - index = var->index; - CError_ASSERT(956, index != 0); - - Bv_SetBit(index, IRO_VarKills); - } - } - - list = list->nextList; - } - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) - Bv_Or(IRO_FuncKills, IRO_VarKills); -} - -static void GetKillsByFunctionCall(IROLinear *linear) { - IROListNode *resultList; - IROLinear *nd; - IROListNode *list; - IROListNode *scan; - IROLinear *inner; - Boolean result; - Boolean foundLinear; - Object *obj; - ObjectList *killList; - ObjectList *olist; - - result = 0; - - if ( - (inner = linear->u.funccall.linear8) && - copts.opt_pointer_analysis && - inner->pointsToFunction && - FunctionName - ) - { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList); - if (resultList) { - for (scan = resultList; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 1; - break; - } - - foundLinear = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundLinear = 1; - obj = nd->u.node->data.objref; - CError_ASSERT(1028, obj != NULL); - - killList = NULL; - PointerAnalysis_GetFunctionKills(obj, linear, &killList); - - for (olist = killList; olist; olist = olist->next) { - if (!olist->object) { - result = 1; - break; - } - } - - while (killList) { - ObjectList *next = killList->next; - IRO_free(killList); - killList = next; - } - - if (result) - break; - } - } - - if (!foundLinear) - result = 1; - if (result) - break; - } - - if (!result) { - for (scan = resultList; scan; scan = scan->nextList) { - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - obj = nd->u.node->data.objref; - killList = NULL; - PointerAnalysis_GetFunctionKills(obj, linear, &killList); - - for (olist = killList; olist; olist = olist->next) { - VarRecord *var; - int index; - - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(1079, var != NULL); - - index = var->index; - CError_ASSERT(1081, index != 0); - - Bv_SetBit(index, IRO_VarKills); - } - - while (killList) { - ObjectList *next = killList->next; - IRO_free(killList); - killList = next; - } - } - } - } - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) - Bv_Or(IRO_FuncKills, IRO_VarKills); -} - -void IRO_GetKills(IROLinear *linear) { - VarRecord *var; - - switch (linear->type) { - case IROLinearOp1Arg: - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - IROLinear *assigned; - int index; - - var = IRO_FindAssigned(linear); - index = 0; - if (var) index = var->index; - Bv_SetBit(index, IRO_VarKills); - - if (!index) - GetKillsByIndirectAssignment(linear); - } - break; - case IROLinearFunccall: - GetKillsByFunctionCall(linear); - break; - case IROLinearAsm: { - IAEffects effects; - int i; - - CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects); - for (i = 0; i < effects.numoperands; i++) { - switch (effects.operands[i].type) { - case IAEffect_1: - case IAEffect_2: - case IAEffect_4: - if ((var = IRO_FindVar(effects.operands[i].object, 0, 1))) - Bv_SetBit(var->index, IRO_VarKills); - break; - } - } - - if (effects.x1 || effects.x4) - Bv_Or(IRO_FuncKills, IRO_VarKills); - break; - } - } -} - -void IRO_CheckInit(void) { - IRONode *fnode; - IROLinear *nd; - VarRecord *var; - ObjectList *olist; - int flag; - int i; - BitVector *bv; - - IRO_MakeReachable(IRO_FirstNode); - fnode = IRO_FirstNode; - Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1); - - while (fnode) { - Bv_AllocVector(&fnode->x16, IRO_NumVars + 1); - Bv_AllocVector(&fnode->x1E, IRO_NumVars + 1); - - for (nd = fnode->first; nd; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - if (nd->flags & IROLF_Ind) { - if (!(nd->flags & IROLF_Assigned) || (nd->flags & IROLF_Used)) { - if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 1))) { - if (!Bv_IsBitSet(var->index, fnode->x1E)) - Bv_SetBit(var->index, fnode->x16); - } - } - } else { - if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 0))) { - Bv_SetBit(var->index, fnode->x1E); - } - } - } else if (nd->type == IROLinearOp2Arg && nd->nodetype == EASS) { - if ((var = IRO_FindAssigned(nd))) - Bv_SetBit(var->index, fnode->x1E); - } else if (nd->type == IROLinearAsm) { - IAEffects effects; - - CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects); - for (i = 0; i < effects.numoperands; i++) { - var = IRO_FindVar(effects.operands[i].object, 0, 1); - switch (effects.operands[i].type) { - case IAEffect_1: - case IAEffect_2: - case IAEffect_4: - Bv_SetBit(var->index, fnode->x1E); - break; - } - } - } - - if (nd == fnode->last) - break; - } - - fnode = fnode->nextnode; - } - - Bv_AllocVector(&bv, IRO_NumVars + 1); - - do { - flag = 0; - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - Bv_Copy(fnode->x1E, bv); - for (i = 0; i < fnode->numpred; i++) - Bv_Or(IRO_NodeTable[fnode->pred[i]]->x1E, bv); - if (!Bv_Compare(bv, fnode->x1E)) { - Bv_Copy(bv, fnode->x1E); - flag = 1; - } - } - } while (flag); - - Bv_Clear(IRO_VarKills); - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (fnode->x36) { - Bv_Copy(fnode->x16, bv); - for (i = 0; i < fnode->numpred; i++) - Bv_Minus(IRO_NodeTable[fnode->pred[i]]->x1E, bv); - Bv_Or(bv, IRO_VarKills); - } - } - - for (olist = locals; olist; olist = olist->next) { - if ((var = IRO_FindVar(olist->object, 0, 1)) && Bv_IsBitSet(var->index, IRO_VarKills)) { - VarInfo *vi = olist->object->u.var.info; - if (!IsTempName(olist->object->name) && !is_volatile_object(olist->object)) { - if (!IS_TYPE_CLASS(olist->object->type) || !CClass_IsEmpty(TYPE_CLASS(olist->object->type))) { - CError_SetErrorToken(&vi->deftoken); - CError_Warning(CErrorStr185, olist->object->name->name); - } - } - } - } - - IRO_CheckForUserBreak(); -} - -static void RewriteIndDec(void) { - IROLinear *add; - IROLinear *indirect; - IROLinear *Int; - IROLinear *nd; - CInt64 value; - IROList list; - - for (nd = IRO_FirstLinear; nd; nd = nd->next) { - if ( - nd->type == IROLinearOp1Arg && - (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC) && - !(nd->flags & IROLF_Reffed) - ) { - indirect = nd->u.monadic; - if ( - indirect->type == IROLinearOp1Arg && - indirect->nodetype == EINDIRECT && - indirect->u.monadic->type == IROLinearOp1Arg && - indirect->u.monadic->nodetype == EBITFIELD - ) { - value = IRO_GetSelfAssignmentVal(nd); - IRO_InitList(&list); - - nd->type = IROLinearOp2Arg; - nd->nodetype = EASS; - nd->u.diadic.left = indirect; - IRO_DuplicateExpr(indirect, &list); - - Int = IRO_NewIntConst(value, indirect->rtype); - Int->flags |= IROLF_Used | IROLF_Reffed; - - add = IRO_NewLinear(IROLinearOp2Arg); - add->nodetype = EADD; - add->u.diadic.left = list.tail; - add->u.diadic.left->flags = 0; - add->u.diadic.left->flags |= IROLF_Used | IROLF_Reffed; - add->u.diadic.right = Int; - add->rtype = indirect->rtype; - add->flags = 0; - add->flags |= IROLF_Used | IROLF_Reffed; - - nd->u.diadic.right = add; - - IRO_AddToList(Int, &list); - IRO_AddToList(add, &list); - IRO_PasteAfter(list.head, list.tail, indirect); - } - } - } -} - -void IRO_RewriteBitFieldTemps(void) { - IROLinear *nd; - IROLinear *expr2; - Object *obj; - VarRecord *var; - IROList list; - - for (nd = IRO_FirstLinear; nd; nd = nd->next) { - if ((obj = IRO_IsVariable(nd)) && (nd->flags & IROLF_BitfieldIndirect)) { - var = IRO_FindVar(obj, 0, 1); - CError_ASSERT(1526, var != NULL); - - expr2 = var->x1E; - CError_ASSERT(1532, expr2 != NULL); - - IRO_InitList(&list); - IRO_DuplicateExpr(expr2, &list); - IRO_NopOut(nd->u.monadic); - nd->u.monadic = list.tail; - IRO_Paste(list.head, list.tail, nd); - } - } -} - -static Boolean FunctionCallMightUseOrKillAnyAddressedVar(IROLinear *funccall) { - IROLinear *funcnd; - IROLinear *nd; - IROListNode *scan; - IROListNode *resultList; - ObjectList *olist; - ObjectList *killList; - VarRecord *var; - Boolean result; - Boolean foundObjRef; - Object *obj; - - result = 0; - - funcnd = funccall->u.funccall.linear8; - if (funcnd && copts.opt_pointer_analysis && funcnd->pointsToFunction && FunctionName) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, funcnd, &resultList); - - if (resultList) { - for (scan = resultList; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 1; - break; - } - - foundObjRef = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundObjRef = 1; - obj = nd->u.node->data.objref; - CError_ASSERT(1592, obj != NULL); - - killList = NULL; - PointerAnalysis_GetFunctionKills(obj, funccall, &killList); - for (olist = killList; olist; olist = olist->next) { - if (!olist->object) { - result = 1; - } else { - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(1604, var != NULL); - if (var->xB) - result = 1; - } - - if (result) - break; - } - - while (killList) { - ObjectList *next = killList->next; - IRO_free(killList); - killList = next; - } - - if (!result) { - killList = NULL; - PointerAnalysis_GetFunctionDependencies(obj, funccall, &killList); - for (olist = killList; olist; olist = olist->next) { - if (!olist->object) { - result = 1; - } else { - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(1632, var != NULL); - if (var->xB) - result = 1; - } - - if (result) - break; - } - - while (killList) { - ObjectList *next = killList->next; - IRO_free(killList); - killList = next; - } - } - - if (result) - break; - } - } - - if (!foundObjRef) - result = 1; - if (result) - break; - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - return result; -} - -static Boolean IndirectMightUseOrKillAnyAddressedVar(IROLinear *indirect) { - Boolean result; - IROLinear *inner; - IROLinear *nd; - IROListNode *scan; - IROListNode *resultList; - Boolean foundObjRef; - Object *obj; - VarRecord *var; - - result = 0; - - if ( - indirect && - indirect->type == IROLinearOp1Arg && - indirect->nodetype == EINDIRECT && - (inner = indirect->u.monadic) && - copts.opt_pointer_analysis && - inner->pointsToFunction && - FunctionName - ) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList); - if (resultList) { - for (scan = resultList; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 1; - break; - } - - foundObjRef = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundObjRef = 1; - obj = nd->u.node->data.objref; - CError_ASSERT(1723, obj != NULL); - var = IRO_FindVar(obj, 1, 1); - CError_ASSERT(1725, var != NULL); - - if (var->xB) - result = 1; - } - } - - if (!foundObjRef) - result = 1; - if (result) - break; - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - return result; -} - -void IRO_ScalarizeClassDataMembers(void) { - IROLinear *nd; - VarRecord *var; - Boolean flag; - Object *obj; - IndirectRecord *irec; - IndirectRecordMatch *match; - IROLinear *tmp; - - nd = IRO_FirstLinear; - IRO_FirstIndirectRecord = NULL; - IRO_LastIndirectRecord = NULL; - RewriteIndDec(); - IRO_DumpAfterPhase("RewriteIndDec", 0); - flag = 0; - - while (nd) { - if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT) { - CheckAddress(nd, &flag); - } - if (nd->type == IROLinearAsm) { - IAEffects effects; - SInt32 i; - CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects); - for (i = 0; i < effects.numoperands; i++) { - if ((var = IRO_FindVar(effects.operands[i].object, 0, 1))) - CheckAddressConsistency(nd, var, -1, &stvoid); - else - CError_FATAL(1823); - } - } - if (nd->type == IROLinearFunccall && !flag) - flag = FunctionCallMightUseOrKillAnyAddressedVar(nd); - - nd = nd->next; - } - - if (flag) - DisableAddressedEntries(); - - for (irec = IRO_FirstIndirectRecord; irec; irec = irec->next) { - if (!(irec->flags & 1)) { - IROList list1; - IROList list2; - - obj = create_temp_object(irec->type); - var = IRO_FindVar(obj, 1, 1); - for (match = irec->matches; match; match = match->otherMatches) { - IRO_InitList(&list1); - IRO_InitList(&list2); - IRO_DuplicateExpr(match->nd, &list1); - IRO_DuplicateExpr(match->nd, &list2); - if (match->nd->type == IROLinearOperand && match->nd->u.node->type == EOBJREF) { - tmp = IRO_LocateFather(match->nd); - if (irec->flags & 2) { - tmp->flags |= IROLF_BitfieldIndirect; - var->x1A = match->nd->rtype; - var->x1E = list2.tail; - } - match->nd->u.node = create_objectrefnode(obj); - irec->x26 = list2.tail; - } else { - tmp = IRO_LocateFather(match->nd); - if (irec->flags & 2) { - tmp->flags |= IROLF_BitfieldIndirect; - var->x1A = match->nd->rtype; - var->x1E = list2.tail; - } - irec->x26 = list2.tail; - - IRO_NopOut(tmp->u.monadic); - tmp->u.monadic = IRO_NewLinear(IROLinearOperand); - tmp->u.monadic->u.node = create_objectrefnode(obj); - tmp->u.monadic->rtype = match->nd->rtype; - tmp->u.monadic->index = ++IRO_NumLinear; - tmp->u.monadic->flags |= IROLF_Ind | IROLF_Reffed; - IRO_NopOut(match->nd); - IRO_PasteAfter(tmp->u.monadic, tmp->u.monadic, match->nd); - } - } - - if (ObjectIsArg(irec->var->object)) { - IROLinear *op1; - IROLinear *op2; - IROLinear *op3; - IROLinear *op4; - IROLinear *op5; - - op1 = IRO_NewLinear(IROLinearOperand); - op1->u.node = create_objectrefnode(obj); - op1->rtype = op1->u.node->data.objref->type; - op1->index = ++IRO_NumLinear; - op1->flags |= IROLF_Ind | IROLF_Assigned; - - op2 = list1.tail; - - op3 = IRO_NewLinear(IROLinearOp1Arg); - op3->nodetype = EINDIRECT; - op3->rtype = irec->type; - op3->u.monadic = op1; - op3->index = ++IRO_NumLinear; - op3->flags |= IROLF_Assigned; - - op4 = IRO_NewLinear(IROLinearOp1Arg); - op4->nodetype = EINDIRECT; - op4->rtype = irec->type; - op4->u.monadic = op2; - op4->index = ++IRO_NumLinear; - op4->flags |= IROLF_Reffed; - - op5 = IRO_NewLinear(IROLinearOp2Arg); - op5->nodetype = EASS; - op5->u.diadic.left = op3; - op5->u.diadic.right = op4; - op5->rtype = irec->type; - op5->index = ++IRO_NumLinear; - - op2->next = op4; - op4->next = op1; - op1->next = op3; - op3->next = op5; - - IRO_PasteAfter(list1.head, op5, IRO_FirstLinear); - } - } - } - - IRO_CheckForUserBreak(); -} - -static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag) { - IROLinear *inner; - VarRecord *var; - Boolean result; - - inner = nd->u.monadic; - if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD) - inner = inner->u.monadic; - - result = 0; - - if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF) { - if (IS_TYPE_CLASS(inner->u.node->data.objref->type) || IS_TYPE_STRUCT(inner->u.node->data.objref->type) || - IS_TYPE_ARRAY(inner->u.node->data.objref->type)) { - if (inner->u.node->data.objref->datatype == DLOCAL) { - var = IRO_FindVar(inner->u.node->data.objref, 0, 1); - CError_ASSERT(2240, var != NULL); - CheckAddressConsistency(nd, var, 0, nd->rtype); - result = 1; - } - } - } else if ( - inner->type == IROLinearOp2Arg && - inner->nodetype == EADD && - inner->u.diadic.left->type == IROLinearOperand && - inner->u.diadic.left->u.node->type == EOBJREF) { - if ( - inner->u.diadic.right->type == IROLinearOperand && - inner->u.diadic.right->u.node->type == EINTCONST && - inner->u.diadic.right->u.node->data.intval.hi == 0) { - if ( - IS_TYPE_CLASS(inner->u.diadic.left->u.node->data.objref->type) || - IS_TYPE_STRUCT(inner->u.diadic.left->u.node->data.objref->type) || - IS_TYPE_ARRAY(inner->u.diadic.left->u.node->data.objref->type) - ) { - if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) { - var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1); - CError_ASSERT(2267, var != NULL); - CheckAddressConsistency(nd, var, inner->u.diadic.right->u.node->data.intval.lo, nd->rtype); - result = 1; - } - } - } else { - if ( - IS_TYPE_CLASS(inner->u.diadic.left->u.node->data.objref->type) || - IS_TYPE_STRUCT(inner->u.diadic.left->u.node->data.objref->type) || - IS_TYPE_ARRAY(inner->u.diadic.left->u.node->data.objref->type) - ) { - if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) { - var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1); - CheckAddressConsistency(nd, var, -1, nd->rtype); - result = 1; - } - } - } - } - - if (!result && !*resultFlag) { - *resultFlag = IndirectMightUseOrKillAnyAddressedVar(nd); - } - - return 0; -} - -static Boolean CheckAddressConsistency(IROLinear *nd, VarRecord *var, SInt32 addend, Type *type) { - IndirectRecord *rp; - IndirectRecordMatch *match; - UInt32 flag; - IROLinear *inner; - UInt32 start_bit; - UInt32 end_bit; - - flag = 0; - inner = nd->u.monadic; - if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD) { - start_bit = TYPE_BITFIELD(inner->rtype)->offset + 8 * addend; - end_bit = start_bit + TYPE_BITFIELD(inner->rtype)->bitlength - 1; - } else { - start_bit = 8 * addend; - end_bit = start_bit + 8 * type->size - 1; - } - - if (var->xB && !copts.opt_pointer_analysis) - return 0; - - if (nd->rtype && CParser_IsVolatile(nd->rtype, nd->nodeflags & ENODE_FLAG_QUALS)) - addend = -1; - if (is_volatile_object(var->object)) - addend = -1; - - for (rp = IRO_FirstIndirectRecord; rp; rp = rp->next) { - if (rp->var->index == var->index) { - if (rp->flags & 1) - return 0; - - if (addend == -1) { - flag = 1; - break; - } - - if (IRO_TypesEqual(rp->type, type) && rp->startbit == start_bit && rp->endbit == end_bit) { - match = oalloc(sizeof(IndirectRecordMatch)); - match->nd = inner; - match->otherMatches = NULL; - if (!rp->matches) { - rp->matches = match; - } else { - match->otherMatches = rp->matches; - rp->matches = match; - } - - IRO_Dump("Exact Match of Type and bits at %d and %d\n", rp->linear->index, nd->index); - IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit); - return 1; - } - - if (rp->startbit == start_bit && rp->endbit == end_bit && !IRO_TypesEqual(rp->type, type)) { - IRO_Dump("match on bits but mismatch on type %d and %d\n", rp->linear->index, nd->index); - IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit); - flag = 1; - break; - } - - if (rp->startbit >= start_bit && end_bit >= rp->startbit) { - IRO_Dump("Overlap detected --1 %d and %d\n", rp->linear->index, nd->index); - IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit); - flag = 1; - break; - } - - if (rp->startbit < start_bit && rp->endbit >= start_bit) { - IRO_Dump("Overlap detected --2 %d and %d\n", rp->linear->index, nd->index); - IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit); - flag = 1; - break; - } - } - } - - if (flag) { - DisableEntries(rp); - if (addend >= 0) - return 0; - } - - IRO_Dump("Create Entry at %d\n", nd->index); - IRO_Dump("start_bit=%d,end_bit=%d\n", start_bit, end_bit); - - rp = oalloc(sizeof(IndirectRecord)); - rp->linear = nd; - rp->flags = 0; - rp->var = var; - rp->addend = addend; - rp->size = type->size; - rp->type = type; - rp->next = NULL; - rp->matches = oalloc(sizeof(IndirectRecordMatch)); - rp->matches->nd = inner; - rp->matches->otherMatches = NULL; - rp->startbit = start_bit; - rp->endbit = end_bit; - - if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT && - nd->u.monadic->type == IROLinearOp1Arg && nd->u.monadic->nodetype == EBITFIELD) - rp->flags |= 2; - - if (!(IS_TYPE_FLOAT(type) || IS_TYPE_INT(type) || IS_TYPE_POINTER_ONLY(type)) || - addend == -1 || ((inner->flags & IROLF_4000) && ObjectIsArg(var->object))) - rp->flags |= 1; - - if (IRO_FirstIndirectRecord) - IRO_LastIndirectRecord->next = rp; - else - IRO_FirstIndirectRecord = rp; - IRO_LastIndirectRecord = rp; - return 1; -} - -static void DisableEntries(IndirectRecord *irec) { - IndirectRecord *scan; - - for (scan = IRO_FirstIndirectRecord; scan; scan = scan->next) { - if (irec->var->index == scan->var->index) - scan->flags |= 1; - } -} - -static void DisableAddressedEntries(void) { - IndirectRecord *scan; - - for (scan = IRO_FirstIndirectRecord; scan; scan = scan->next) { - if (scan->var->xB) - scan->flags |= 1; - } -} - -static UInt32 ObjectIsArg(Object *obj) { - ObjectList *scan; - - for (scan = arguments; scan; scan = scan->next) { - if (scan->object == obj) - return 1; - } - - return 0; -} - |