diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CInline.c')
-rw-r--r-- | compiler_and_linker/unsorted/CInline.c | 4206 |
1 files changed, 0 insertions, 4206 deletions
diff --git a/compiler_and_linker/unsorted/CInline.c b/compiler_and_linker/unsorted/CInline.c deleted file mode 100644 index de51ab7..0000000 --- a/compiler_and_linker/unsorted/CInline.c +++ /dev/null @@ -1,4206 +0,0 @@ -#include "compiler/CInline.h" -#include "compiler/CABI.h" -#include "compiler/CClass.h" -#include "compiler/CError.h" -#include "compiler/CException.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInit.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/COptimizer.h" -#include "compiler/CParser.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CTemplateNew.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/Exceptions.h" -#include "compiler/InlineAsm.h" -#include "compiler/ObjGenMachO.h" -#include "compiler/Switch.h" -#include "compiler/enode.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct IDTrans { - struct IDTrans *next; - SInt32 from; - SInt32 to; -} IDTrans; - -typedef struct LabelTrans { - struct LabelTrans *next; - CLabel **labelptr; - short id; -} LabelTrans; - -typedef struct UIDTemp { - struct UIDTemp *next; - Object *object; - SInt32 uid; -} UIDTemp; - -typedef struct CI_Export { - struct CI_Export *next; - Object *object; - CI_FuncData *funcdata; - Boolean xC; -} CI_Export; - -typedef struct AObject { - Object *object; - ENode *expr1; - ENode *expr2; -} AObject; - -typedef struct CI_StmtLink { - struct CI_StmtLink *next; - Statement *stmt; - CI_Statement *ciStmt; -} CI_StmtLink; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -static CInlineCopyMode enode_copymode; -static Boolean enode_globalcopy; -static IDTrans *enode_idtrans; -static Object **local_dobjects; -static AObject *local_aobjects; -static CI_Var *loc_args; -static CI_Var *loc_vars; -static Boolean inline_expanded; -static Boolean any_inline_expanded; -static short cinline_level; -static LabelTrans *cinline_label_trans; -static Statement *cinline_first_stmt; -static ENode *cinline_stmtlevelexpr[16]; -static short cinline_stmtlevelexprs; -static Boolean cinline_unconditionalpart; -static Boolean cinline_serialize_stmt; -static CI_Export *cinline_exportlist; // type? -static CI_Action *cinline_actionlist; -CI_Action *cinline_tactionlist; -static ObjectList *cinline_freflist; -static Boolean cinline_gendeps; -static Statement *cinline_serial_stmt; -static Statement *cinline_cur_serial_stmt; -static UIDTemp *cinline_uid_temps; -static Boolean cinline_has_sideeffect; -static SInt32 inline_max_size; -static Boolean recursive_inline; -static Object *expanding_function; -static Boolean cinline_funccallfound; - -// forward decls -static ENode *CInline_FoldConst(ENode *expr); -static ENode *CInline_CopyNodes(ENode *node); -static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 size, SInt32 level); -static ENode *CInline_SerializeExpr(ENode *expr); -static void CInline_AddFRefList_InlineFunc(CI_FuncData *data); - -void CInline_Init(void) { - cinline_exportlist = NULL; - cinline_actionlist = NULL; - cinline_tactionlist = NULL; - cinline_gendeps = 0; -} - -static ENode *CInline_MakeNotNot(ENode *expr) { - expr = CInline_FoldConst(expr); - - if (!ENODE_IS(expr, EINTCONST)) { - expr = makemonadicnode(expr, ELOGNOT); - expr->rtype = CParser_GetBoolType(); - expr = makemonadicnode(expr, ELOGNOT); - } else { - expr->data.intval = CInt64_Not(CInt64_Not(expr->data.intval)); - } - - return expr; -} - -static ENode *CInline_FoldConst(ENode *expr) { - ENode *inner; - ENode *right; - ENode *left; - ENodeList *list; - - switch (expr->type) { - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ETEMP: - case ELABEL: - case EOBJLIST: - case EINSTRUCTION: - case EVECTOR128CONST: - return expr; - - case EMONMIN: - case EBINNOT: - case ELOGNOT: - expr->data.monadic = CInline_FoldConst(expr->data.monadic); - inner = expr->data.monadic; - switch (inner->type) { - case EINTCONST: - if (!ENODE_IS(expr, ELOGNOT)) { - inner->data.intval = CMach_CalcIntMonadic( - expr->rtype, CParser_GetOperator(expr->type), inner->data.intval); - } else { - inner->data.intval = CInt64_Not(inner->data.intval); - } - inner->rtype = expr->rtype; - return inner; - - case EFLOATCONST: - if (ENODE_IS(expr, ELOGNOT)) { - inner->type = EINTCONST; - CInt64_SetLong(&inner->data.intval, CMach_FloatIsZero(inner->data.floatval)); - } else { - inner->data.floatval = CMach_CalcFloatMonadic( - expr->rtype, CParser_GetOperator(expr->type), inner->data.floatval); - } - inner->rtype = expr->rtype; - return inner; - } - - return expr; - - case ETYPCON: - expr->data.monadic = CInline_FoldConst(expr->data.monadic); - switch (expr->data.monadic->type) { - case EINTCONST: - switch (expr->rtype->type) { - case TYPEFLOAT: - expr->type = EFLOATCONST; - expr->data.floatval = CMach_CalcFloatConvertFromInt( - expr->data.monadic->rtype, expr->data.monadic->data.intval); - return expr; - - case TYPEINT: - expr->type = EINTCONST; - expr->data.intval = CExpr_IntConstConvert( - expr->rtype, expr->data.monadic->rtype, expr->data.monadic->data.intval); - break; - } - break; - - case EFLOATCONST: - switch (expr->rtype->type) { - case TYPEFLOAT: - expr->type = EFLOATCONST; - expr->data.floatval = CMach_CalcFloatConvert( - expr->rtype, expr->data.monadic->data.floatval); - return expr; - - case TYPEINT: - expr->type = EINTCONST; - expr->data.intval = CMach_CalcIntConvertFromFloat( - expr->rtype, expr->data.monadic->data.floatval); - return expr; - } - break; - } - - return expr; - - case EPOSTINC: - case EPOSTDEC: - expr->data.monadic = CInline_FoldConst(expr->data.monadic); - switch (expr->data.monadic->type) { - case EINTCONST: - case EFLOATCONST: - expr->data.monadic->rtype = expr->rtype; - return expr->data.monadic; - } - - return expr; - - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EFORCELOAD: - case EBITFIELD: - expr->data.monadic = CInline_FoldConst(expr->data.monadic); - return expr; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case EAND: - case EXOR: - case EOR: - expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left); - expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right); - if ((left = expr->data.diadic.left)->type == (right = expr->data.diadic.right)->type) { - switch (left->type) { - case EINTCONST: - left->data.intval = CMach_CalcIntDiadic( - expr->rtype, - expr->data.diadic.left->data.intval, - CParser_GetOperator(expr->type), - right->data.intval); - left->rtype = expr->rtype; - return left; - - case EFLOATCONST: - left->data.floatval = CMach_CalcFloatDiadic( - expr->rtype, - expr->data.diadic.left->data.floatval, - CParser_GetOperator(expr->type), - right->data.floatval); - left->rtype = expr->rtype; - return left; - } - } - - return expr; - - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left); - expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right); - if ((left = expr->data.diadic.left)->type == (right = expr->data.diadic.right)->type) { - switch (left->type) { - case EINTCONST: - left->data.intval = CMach_CalcIntDiadic( - left->rtype, - expr->data.diadic.left->data.intval, - CParser_GetOperator(expr->type), - right->data.intval); - left->rtype = expr->rtype; - return left; - - case EFLOATCONST: - CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool( - left->rtype, - expr->data.diadic.left->data.floatval, - CParser_GetOperator(expr->type), - right->data.floatval - )); - left->type = EINTCONST; - left->rtype = expr->rtype; - return left; - } - } - - return expr; - - case ELAND: - expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left); - if (iszero(expr->data.diadic.left)) - return expr->data.diadic.left; - if (isnotzero(expr->data.diadic.left)) - return CInline_MakeNotNot(expr->data.diadic.right); - - expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right); - if (isnotzero(expr->data.diadic.right)) - return CInline_MakeNotNot(expr->data.diadic.left); - - return expr; - - case ELOR: - expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left); - if (iszero(expr->data.diadic.left)) - return CInline_MakeNotNot(expr->data.diadic.right); - if (isnotzero(expr->data.diadic.left)) - return CInline_MakeNotNot(expr->data.diadic.left); - - expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right); - if (iszero(expr->data.diadic.right)) - return CInline_MakeNotNot(expr->data.diadic.left); - - return expr; - - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EROTL: - case EROTR: - expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left); - expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right); - return expr; - - case ECOND: - expr->data.cond.cond = CInline_FoldConst(expr->data.cond.cond); - if (isnotzero(expr->data.cond.cond)) - return CInline_FoldConst(expr->data.cond.expr1); - if (iszero(expr->data.cond.cond)) - return CInline_FoldConst(expr->data.cond.expr2); - - expr->data.cond.expr1 = CInline_FoldConst(expr->data.cond.expr1); - expr->data.cond.expr2 = CInline_FoldConst(expr->data.cond.expr2); - return expr; - - case EMFPOINTER: - expr->data.mfpointer.accessnode = CInline_FoldConst(expr->data.mfpointer.accessnode); - expr->data.mfpointer.mfpointer = CInline_FoldConst(expr->data.mfpointer.mfpointer); - return expr; - - case EFUNCCALL: - case EFUNCCALLP: - expr->data.funccall.funcref = CInline_FoldConst(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - list->node = CInline_FoldConst(list->node); - return expr; - - case ENULLCHECK: - expr->data.nullcheck.nullcheckexpr = CInline_FoldConst(expr->data.nullcheck.nullcheckexpr); - expr->data.nullcheck.condexpr = CInline_FoldConst(expr->data.nullcheck.condexpr); - return expr; - - case EMEMBER: - if (expr->data.emember->expr) - expr->data.emember->expr = CInline_FoldConst(expr->data.emember->expr); - return expr; - - default: - CError_FATAL(421); - return expr; - } -} - -// unknown name -CW_INLINE SInt32 CInline_GetLocalID2(Object *object) { - ObjectList *list; - SInt32 counter; - - for (list = locals, counter = 0; list; list = list->next) { - if (list->object->datatype == DLOCAL) { - if (list->object == object) - return counter; - counter++; - } - } - - return -1; -} - -SInt32 CInline_GetLocalID(Object *object) { - ObjectList *list; - SInt32 counter; - - if (object) { - for (list = arguments, counter = 0; list; list = list->next, counter++) { - if (list->object == object) { - loc_args[counter].xD = 1; - loc_args[counter].xE = 0; - return counter - 0x7FFFFFFF; - } - } - - counter = CInline_GetLocalID2(object); - CError_ASSERT(465, counter >= 0); - loc_vars[counter].xD = 1; - return counter + 1; - } - - return 0; -} - -static Boolean CInline_IsTrivialExpression(ENode *expr) { - while (1) { - switch (expr->type) { - case EINTCONST: - case EFLOATCONST: - case EOBJREF: - case EARGOBJ: - case ELOCOBJ: - case EOBJLIST: - case EVECTOR128CONST: - return 0; - - case ESTRINGCONST: - return copts.dont_reuse_strings; - - case EMEMBER: - if (expr->data.emember->expr) - return CInline_IsTrivialExpression(expr->data.emember->expr); - return 0; - - case EINDIRECT: - if (ENODE_IS(expr->data.monadic, EOBJREF)) { - if (expr->data.monadic->data.objref->datatype == DLOCAL && - !(expr->data.monadic->data.objref->flags & OBJECT_FLAGS_2)) - return 0; - - if (is_const_object(expr->data.monadic->data.objref)) - return 0; - - return 1; - } - - return 1; - - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EFORCELOAD: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case EFUNCCALL: - case EFUNCCALLP: - case EMFPOINTER: - case ENULLCHECK: - case EPRECOMP: - case ETEMP: - case ELABEL: - case EINSTRUCTION: - return 1; - - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case ETYPCON: - case EBITFIELD: - expr = expr->data.monadic; - continue; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case ECOMMA: - case EROTL: - case EROTR: - if (CInline_IsTrivialExpression(expr->data.diadic.left)) - return 1; - expr = expr->data.diadic.right; - continue; - - case ECOND: - if (CInline_IsTrivialExpression(expr->data.cond.cond)) - return 1; - if (CInline_IsTrivialExpression(expr->data.cond.expr1)) - return 1; - expr = expr->data.cond.expr2; - continue; - - default: - CError_FATAL(582); - } - } -} - -Boolean CInline_ExpressionHasSideEffect(ENode *expr) { - while (1) { - switch (expr->type) { - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ETEMP: - case EARGOBJ: - case ELOCOBJ: - case ELABEL: - case EOBJLIST: - case EVECTOR128CONST: - return 0; - - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case EFUNCCALL: - case EFUNCCALLP: - case EINSTRUCTION: - return 1; - - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - expr = expr->data.monadic; - continue; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case ECOMMA: - case EROTL: - case EROTR: - if (CInline_ExpressionHasSideEffect(expr->data.diadic.left)) - return 1; - expr = expr->data.diadic.right; - continue; - - case EMEMBER: - if (expr->data.emember->expr) - return CInline_ExpressionHasSideEffect(expr->data.emember->expr); - return 0; - - case EMFPOINTER: - if (CInline_ExpressionHasSideEffect(expr->data.mfpointer.accessnode)) - return 1; - expr = expr->data.mfpointer.mfpointer; - continue; - - case ENULLCHECK: - if (CInline_ExpressionHasSideEffect(expr->data.nullcheck.nullcheckexpr)) - return 1; - expr = expr->data.nullcheck.condexpr; - continue; - - case ECOND: - if (CInline_ExpressionHasSideEffect(expr->data.cond.cond)) - return 1; - if (CInline_ExpressionHasSideEffect(expr->data.cond.expr1)) - return 1; - expr = expr->data.cond.expr2; - continue; - - default: - CError_FATAL(689); - } - } -} - -static ENode *CInline_CopyExpressionSave(ENode *expr) { - CInlineCopyMode save_copymode; - Boolean save_globalcopy; - IDTrans *save_idtrans; - - save_globalcopy = enode_globalcopy; - enode_globalcopy = 1; - - save_copymode = enode_copymode; - enode_copymode = CopyMode4; - - save_idtrans = enode_idtrans; - enode_idtrans = NULL; - - expr = CInline_CopyNodes(expr); - - enode_globalcopy = save_globalcopy; - enode_copymode = save_copymode; - enode_idtrans = save_idtrans; - - return expr; -} - -static SInt32 CInline_TranslateID(SInt32 id) { - IDTrans *trans; - - for (trans = enode_idtrans; trans; trans = trans->next) { - if (trans->from == id) - return trans->to; - } - - trans = lalloc(sizeof(IDTrans)); - trans->next = enode_idtrans; - enode_idtrans = trans; - - trans->from = id; - trans->to = CParser_GetUniqueID(); - - return trans->to; -} - -static short CInline_GetLabelStatementNumber(HashNameNode *name) { - Statement *stmt; - short i; - - for (stmt = cinline_first_stmt, i = 0; stmt; stmt = stmt->next, i++) { - if (stmt->type == ST_LABEL && stmt->label->uniquename == name) - return i; - } - - CError_FATAL(742); - return 0; -} - -static ENodeList *CInline_CopyNodeList(ENodeList *list) { - ENodeList *copy; - ENodeList *first; - ENodeList *last; - - first = NULL; - while (list) { - if (enode_globalcopy) - copy = galloc(sizeof(ENodeList)); - else - copy = lalloc(sizeof(ENodeList)); - - copy->node = CInline_CopyNodes(list->node); - copy->next = NULL; - - if (first) { - last->next = copy; - last = copy; - } else { - first = last = copy; - } - - list = list->next; - } - - return first; -} - -static EMemberInfo *CInline_CopyEMemberInfo(EMemberInfo *mi) { - EMemberInfo *copy; - - if (enode_globalcopy) - copy = galloc(sizeof(EMemberInfo)); - else - copy = lalloc(sizeof(EMemberInfo)); - - *copy = *mi; - if (copy->path) - copy->path = CClass_GetPathCopy(copy->path, enode_globalcopy); - if (copy->expr) - copy->expr = CInline_CopyNodes(copy->expr); - - return copy; -} - -static ENode *CInline_CopyNodes(ENode *node) { - ENode *copy; - - if (enode_globalcopy) - copy = galloc(sizeof(ENode)); - else - copy = lalloc(sizeof(ENode)); - - while (1) { - *copy = *node; - switch (copy->type) { - case ETEMPLDEP: - switch (copy->data.templdep.subtype) { - case TDE_PARAM: - case TDE_SIZEOF: - case TDE_ALIGNOF: - case TDE_QUALNAME: - case TDE_OBJ: - break; - case TDE_CAST: - copy->data.templdep.u.cast.args = CInline_CopyNodeList(copy->data.templdep.u.cast.args); - break; - case TDE_SOURCEREF: - copy->data.templdep.u.sourceref.expr = CInline_CopyNodes(copy->data.templdep.u.sourceref.expr); - break; - case TDE_ADDRESS_OF: - copy->data.templdep.u.monadic = CInline_CopyNodes(copy->data.templdep.u.monadic); - break; - default: - CError_FATAL(840); - } - break; - - case ETEMP: - if (enode_copymode == CopyMode3 && copy->data.temp.uniqueid) - copy->data.temp.uniqueid = CInline_TranslateID(copy->data.temp.uniqueid); - break; - - case ELABEL: - switch (enode_copymode) { - case CopyMode2: - copy->data.precompid = CInline_GetLabelStatementNumber(copy->data.label->uniquename); - return copy; - case CopyMode3: - case CopyMode4: { - LabelTrans *trans = lalloc(sizeof(LabelTrans)); - trans->next = cinline_label_trans; - cinline_label_trans = trans; - trans->id = copy->data.precompid; - trans->labelptr = ©->data.label; - return copy; - } - } - break; - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJLIST: - case EINSTRUCTION: - case EVECTOR128CONST: - break; - - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - copy->data.monadic = CInline_CopyNodes(copy->data.monadic); - break; - - ENODE_CASE_DIADIC_ALL: - copy->data.diadic.left = CInline_CopyNodes(copy->data.diadic.left); - copy->data.diadic.right = CInline_CopyNodes(copy->data.diadic.right); - break; - - case ECOND: - copy->data.cond.cond = CInline_CopyNodes(copy->data.cond.cond); - copy->data.cond.expr1 = CInline_CopyNodes(copy->data.cond.expr1); - copy->data.cond.expr2 = CInline_CopyNodes(copy->data.cond.expr2); - break; - - case EMFPOINTER: - copy->data.mfpointer.accessnode = CInline_CopyNodes(copy->data.mfpointer.accessnode); - copy->data.mfpointer.mfpointer = CInline_CopyNodes(copy->data.mfpointer.mfpointer); - break; - - case EFUNCCALL: - case EFUNCCALLP: - copy->data.funccall.funcref = CInline_CopyNodes(copy->data.funccall.funcref); - copy->data.funccall.args = CInline_CopyNodeList(copy->data.funccall.args); - break; - - case ENULLCHECK: - copy->data.nullcheck.precompid = CInline_TranslateID(copy->data.nullcheck.precompid); - copy->data.nullcheck.nullcheckexpr = CInline_CopyNodes(copy->data.nullcheck.nullcheckexpr); - copy->data.nullcheck.condexpr = CInline_CopyNodes(copy->data.nullcheck.condexpr); - break; - - case EPRECOMP: - copy->data.precompid = CInline_TranslateID(copy->data.precompid); - break; - - case EINDIRECT: - if ( - enode_copymode == CopyMode4 && - ENODE_IS(copy->data.monadic, EARGOBJ) && - local_aobjects[copy->data.monadic->data.longval].object == NULL - ) - { - CError_ASSERT(910, local_aobjects[copy->data.monadic->data.longval].expr1); - copy = CInline_CopyExpressionSave(local_aobjects[copy->data.monadic->data.longval].expr1); - if (copy->rtype != node->rtype) { - if (IS_TYPE_INT(copy->rtype) && IS_TYPE_INT(node->rtype)) - copy = makemonadicnode(copy, ETYPCON); - copy->rtype = node->rtype; - } - return copy; - } - - copy->data.monadic = CInline_CopyNodes(copy->data.monadic); - break; - - case EOBJREF: - if (enode_copymode == CopyMode2) { - ObjectList *list; - int i; - - if (node->data.objref->datatype == DALIAS) { - CExpr_AliasTransform(node); - continue; - } - - if (node->data.objref->datatype == DDATA) - return copy; - - for (list = arguments, i = 0; list; list = list->next, i++) { - if (list->object == copy->data.objref) { - copy->type = EARGOBJ; - copy->data.longval = i; - return copy; - } - } - - i = CInline_GetLocalID2(copy->data.objref); - if (i >= 0) { - copy->type = ELOCOBJ; - copy->data.longval = i; - return copy; - } - - if (node->data.objref->datatype == DLOCAL) - CError_FATAL(949); - } - break; - - case EARGOBJ: - switch (enode_copymode) { - case CopyMode4: - CError_ASSERT(957, local_aobjects[copy->data.longval].object); - copy->type = EOBJREF; - copy->data.objref = local_aobjects[copy->data.longval].object; - return copy; - - case CopyMode3: { - ObjectList *list; - int i; - for (list = arguments, i = 0; list; list = list->next, i++) { - if (i == copy->data.longval) { - copy->type = EOBJREF; - copy->data.objref = list->object; - CError_ASSERT(966, copy->data.objref); - return copy; - } - } - } - - default: - CError_FATAL(971); - } - - case ELOCOBJ: - switch (enode_copymode) { - case CopyMode4: - copy->type = EOBJREF; - copy->data.objref = local_dobjects[copy->data.longval]; - return copy; - - case CopyMode3: { - ObjectList *list; - int i; - for (list = locals, i = 0; list; list = list->next, i++) { - if (i == copy->data.longval) { - copy->type = EOBJREF; - copy->data.objref = list->object; - CError_ASSERT(986, copy->data.objref); - return copy; - } - } - } - - default: - CError_FATAL(991); - } - break; - - case ENEWEXCEPTION: - case ENEWEXCEPTIONARRAY: - copy->data.newexception.initexpr = CInline_CopyNodes(copy->data.newexception.initexpr); - copy->data.newexception.tryexpr = CInline_CopyNodes(copy->data.newexception.tryexpr); - break; - - case EINITTRYCATCH: - copy->data.itc.initexpr = CInline_CopyNodes(copy->data.itc.initexpr); - copy->data.itc.tryexpr = CInline_CopyNodes(copy->data.itc.tryexpr); - copy->data.itc.catchexpr = CInline_CopyNodes(copy->data.itc.catchexpr); - copy->data.itc.result = CInline_CopyNodes(copy->data.itc.result); - break; - - case EMEMBER: - copy->data.emember = CInline_CopyEMemberInfo(copy->data.emember); - break; - - default: - CError_FATAL(1015); - } - - return copy; - } -} - -static void CInline_CheckUsage(ENode *expr, Boolean flag) { - ENodeList *list; - ENode *inner; - - while (1) { - switch (expr->type) { - case EARGOBJ: - loc_args[expr->data.longval].xD = 1; - loc_args[expr->data.longval].xE = 0; - return; - - case ELOCOBJ: - loc_vars[expr->data.longval].xD = 1; - return; - - case EINDIRECT: - if (ENODE_IS((inner = expr->data.monadic), EARGOBJ)) { - loc_args[inner->data.longval].xD = 1; - if (flag) - loc_args[inner->data.longval].xE = 0; - return; - } - expr = expr->data.monadic; - flag = 0; - continue; - - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - expr = expr->data.monadic; - flag = 0; - continue; - - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - expr = expr->data.monadic; - flag = 1; - continue; - - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - CInline_CheckUsage(expr->data.diadic.left, 1); - expr = expr->data.diadic.right; - flag = 0; - continue; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case ECOMMA: - case EROTL: - case EROTR: - CInline_CheckUsage(expr->data.diadic.left, 0); - expr = expr->data.diadic.right; - flag = 0; - continue; - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ETEMP: - case ELABEL: - case EOBJLIST: - case EVECTOR128CONST: - return; - - case EMEMBER: - if (expr->data.emember->expr) - CInline_CheckUsage(expr->data.emember->expr, 0); - return; - - case EFUNCCALL: - case EFUNCCALLP: - CInline_CheckUsage(expr->data.funccall.funcref, 0); - for (list = expr->data.funccall.args; list; list = list->next) - CInline_CheckUsage(list->node, 0); - return; - - case ENULLCHECK: - CInline_CheckUsage(expr->data.nullcheck.nullcheckexpr, 0); - expr = expr->data.nullcheck.condexpr; - flag = 0; - continue; - - case EMFPOINTER: - CInline_CheckUsage(expr->data.mfpointer.accessnode, 0); - expr = expr->data.mfpointer.mfpointer; - flag = 0; - continue; - - case ECOND: - CInline_CheckUsage(expr->data.cond.cond, 0); - CInline_CheckUsage(expr->data.cond.expr1, 0); - expr = expr->data.cond.expr2; - flag = 0; - continue; - - case EINSTRUCTION: - return; - - default: - CError_FATAL(1146); - } - } -} - -ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode) { - enode_copymode = mode; - - switch (mode) { - case CopyMode0: - case CopyMode4: - enode_idtrans = NULL; - enode_globalcopy = 0; - expr = CInline_CopyNodes(expr); - break; - case CopyMode3: - enode_globalcopy = 0; - expr = CInline_CopyNodes(expr); - break; - case CopyMode1: - enode_idtrans = NULL; - enode_globalcopy = 1; - expr = CInline_CopyNodes(expr); - break; - case CopyMode2: - enode_idtrans = NULL; - enode_globalcopy = 1; - expr = CInline_CopyNodes(expr); - CInline_CheckUsage(expr, 0); - break; - } - - return expr; -} - -static UInt8 CInline_GetObjectSFlags(Object *object) { - UInt8 flags; - - switch (object->sclass) { - case 0: - flags = CI_SFLAGS_NoClass; - break; - case TK_REGISTER: - flags = CI_SFLAGS_Register; - break; - case TK_AUTO: - flags = CI_SFLAGS_Auto; - break; - default: - CError_FATAL(1204); - } - - if (object->flags & OBJECT_FLAGS_2) - flags |= CI_SFLAGS_HasObjectFlag2; - - return flags; -} - -static void CInline_SetObjectSFlags(Object *object, UInt8 sflags) { - if (sflags & CI_SFLAGS_HasObjectFlag2) { - object->flags |= OBJECT_FLAGS_2; - sflags &= ~CI_SFLAGS_HasObjectFlag2; - } - - switch (sflags) { - case CI_SFLAGS_NoClass: - object->sclass = 0; - break; - case CI_SFLAGS_Register: - object->sclass = TK_REGISTER; - break; - case CI_SFLAGS_Auto: - object->sclass = TK_AUTO; - break; - default: - CError_FATAL(1229); - } -} - -static Object *CInline_NewLocalObject(Type *type, short qual, UInt8 sflags, int unk) { - Object *object = CParser_NewLocalDataObject(NULL, 1); - object->name = CParser_GetUniqueName(); - object->type = type; - object->qual = qual; - CInline_SetObjectSFlags(object, sflags); - CFunc_SetupLocalVarInfo(object); - return object; -} - -static ENode *CInline_FuncArgConvert(ENode *expr) { - ENode *copy; - - switch (expr->type) { - case EOBJREF: - copy = lalloc(sizeof(ENode)); - *copy = *expr; - return copy; - case ETEMP: - CError_FATAL(1272); - } - - return NULL; -} - -static ENode *CInline_RefArgTransform(ENode *expr, Boolean flag) { - ENodeList *arg; - - while (ENODE_IS(expr, ECOMMA)) - expr = expr->data.diadic.right; - - switch (expr->type) { - case EOBJREF: - case ETEMP: - if (flag) - return CInline_FuncArgConvert(expr); - break; - - case EFUNCCALL: - if (IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_CLASS(TPTR_TARGET(expr->rtype))) { - if ( - ENODE_IS(expr->data.funccall.funcref, EOBJREF) && - CClass_IsConstructor(expr->data.funccall.funcref->data.objref) && - expr->data.funccall.args - ) - return CInline_FuncArgConvert(expr->data.funccall.args->node); - - if ( - TPTR_TARGET(expr->rtype) == expr->data.funccall.functype->functype && - CMach_GetFunctionResultClass(expr->data.funccall.functype) == 1 && - (arg = expr->data.funccall.args) - ) - { - switch (CABI_GetStructResultArgumentIndex(expr->data.funccall.functype)) { - case 0: - break; - case 1: - if ((arg = arg->next)) - break; - CError_FATAL(1313); - default: - CError_FATAL(1314); - } - - return CInline_FuncArgConvert(arg->node); - } - } - break; - } - - return NULL; -} - -static ENode *CInline_SetupArgsExpression(Object *object, CI_FuncData *data, ENodeList *list) { - ENode *commaNodes; - CI_Var *var; - ENodeList *scan; - ENode *expr; - SInt32 i; - Boolean is_oldstyle; - - is_oldstyle = 0; - if (TYPE_FUNC(object->type)->args == &oldstyle) - is_oldstyle = 1; - - local_dobjects = lalloc(sizeof(Object *) * data->numlocals); - local_aobjects = lalloc(sizeof(AObject) * data->numarguments); - - for (i = 0, var = data->locals; i < data->numlocals; i++, var++) { - if (var->xD) { - object = CInline_NewLocalObject(var->type, var->qual, var->sflags, 0); - local_dobjects[i] = object; - if (!var->xE) - object->flags |= OBJECT_FLAGS_2; - } else { - local_dobjects[i] = NULL; - } - } - - for (i = 0, var = data->arguments, scan = list; i < data->numarguments; i++, var++) { - local_aobjects[i].expr2 = NULL; - - if (!var->xD) { - local_aobjects[i].object = NULL; - local_aobjects[i].expr1 = NULL; - } else if ( - scan && - var->xE && - !CInline_IsTrivialExpression(scan->node) && - (!is_oldstyle || scan->node->rtype->size == var->type->size) - ) - { - local_aobjects[i].object = NULL; - local_aobjects[i].expr1 = scan->node; - } else if ( - scan && - var->xE && - IS_TYPE_REFERENCE(var->type) && - (expr = CInline_RefArgTransform(scan->node, 1)) - ) - { - local_aobjects[i].object = NULL; - local_aobjects[i].expr1 = expr; - local_aobjects[i].expr2 = scan->node; - } else { - local_aobjects[i].object = CInline_NewLocalObject(var->type, var->qual, var->sflags, 0); - local_aobjects[i].expr1 = NULL; - } - - if (scan) - scan = scan->next; - } - - commaNodes = NULL; - - for (i = 0, scan = list; scan; scan = scan->next, i++) { - if (i >= data->numarguments) { - if (!commaNodes) - commaNodes = scan->node; - else - commaNodes = makecommaexpression(scan->node, commaNodes); - } else if (!local_aobjects[i].object || local_aobjects[i].expr2) { - if (local_aobjects[i].expr2) { - if (!commaNodes) - commaNodes = local_aobjects[i].expr2; - else - commaNodes = makecommaexpression(local_aobjects[i].expr2, commaNodes); - } else if (!local_aobjects[i].expr1 && CInline_IsTrivialExpression(scan->node)) { - commaNodes = !commaNodes ? scan->node : makecommaexpression(scan->node, commaNodes); - CError_ASSERT(1470, !ENODE_IS(scan->node, EPRECOMP)); - } - } else { - if (is_oldstyle && scan->node->rtype->size != local_aobjects[i].object->type->size) { - scan->node = makemonadicnode(scan->node, ETYPCON); - scan->node->rtype = local_aobjects[i].object->type; - } - - expr = makediadicnode(create_objectnode2(local_aobjects[i].object), scan->node, EASS); - if (!commaNodes) - commaNodes = expr; - else - commaNodes = makecommaexpression(expr, commaNodes); - } - } - - return commaNodes; -} - -static void CInline_ReturnCheckCB(ENode *expr) { - cinline_has_sideeffect = 1; -} - -static ENode *CInline_ReturnCheck(ENode *expr) { - ENode *copy; - - if (ENODE_IS(expr, EFORCELOAD)) - return expr; - - cinline_has_sideeffect = 0; - CExpr_SearchExprTree(expr, CInline_ReturnCheckCB, 3, EINDIRECT, EFUNCCALL, EFUNCCALLP); - - if (!cinline_has_sideeffect) - return expr; - - copy = lalloc(sizeof(ENode)); - *copy = *expr; - copy->type = EFORCELOAD; - - copy->data.monadic = expr; - return copy; -} - -static ENode *CInline_ReturnMemResult(Object *object) { - int index = CABI_GetStructResultArgumentIndex(TYPE_FUNC(object->type)); - if (local_aobjects[index].object == NULL) - return CInline_CopyExpressionSave(local_aobjects[index].expr1); - else - return create_objectnode(local_aobjects[index].object); -} - -static ENode *CInline_InlineFunctionExpression(ENode *expr) { - Object *object; - CI_FuncData *funcdata; - short i; - Boolean flag26; - ENode *argsExpr; - - object = expr->data.funccall.funcref->data.objref; - if (object->datatype == DALIAS) - object = object->u.alias.object; - - funcdata = object->u.func.u.ifuncdata; - if (!funcdata) - return expr; - - if (funcdata->can_inline < CI_CanInline6) { - if (funcdata->can_inline == CI_CanInline3) { - if (cinline_unconditionalpart && cinline_stmtlevelexprs < 16) - cinline_stmtlevelexpr[cinline_stmtlevelexprs++] = expr; - cinline_serialize_stmt = 1; - } - return expr; - } - - flag26 = CMach_GetFunctionResultClass(TYPE_FUNC(object->type)) == 1; - argsExpr = CInline_SetupArgsExpression(object, funcdata, expr->data.funccall.args); - - for (i = 0; i < funcdata->numstatements; i++) { - switch (funcdata->statements[i].type) { - case ST_RETURN: - if (funcdata->statements[i].u.expr) { - ENode *copy = CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4); - if (flag26) { - if (argsExpr) - argsExpr = makecommaexpression(argsExpr, copy); - else - argsExpr = copy; - - argsExpr = makecommaexpression(argsExpr, CInline_ReturnMemResult(object)); - } else { - if (argsExpr) - argsExpr = makecommaexpression(argsExpr, CInline_ReturnCheck(copy)); - else - argsExpr = CInline_ReturnCheck(copy); - } - } - break; - case ST_EXPRESSION: - if (argsExpr) - argsExpr = makecommaexpression(argsExpr, CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4)); - else - argsExpr = CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4); - break; - - default: - CError_FATAL(1632); - } - } - - if (!argsExpr) - argsExpr = nullnode(); - if (!IS_TYPE_VOID(expr->rtype)) - argsExpr->rtype = expr->rtype; - - inline_expanded = 1; - return CInline_FoldConst(argsExpr); -} - -static Boolean CInline_CanExpand(ENode *expr) { - TypeFunc *tfunc; - Object *object; - - object = expr->data.objref; - tfunc = TYPE_FUNC(object->type); - - if ( - IS_TYPE_FUNC(tfunc) && - ((object->qual & Q_INLINE) || (tfunc->flags & FUNC_FLAGS_800)) && - (object->datatype == DFUNC || (object->datatype == DVFUNC && (expr->flags & ENODE_FLAG_80))) - ) - return 1; - - return 0; -} - -static SInt32 CInline_EstimateSizeOfExpr(ENode *expr, SInt32 size, SInt32 level) { - ENodeList *list; - - switch (expr->type) { - ENODE_CASE_MONADIC: - size = CInline_EstimateSizeOfExpr(expr->data.monadic, size, level) + 1; - break; - - ENODE_CASE_DIADIC_ALL: - size = CInline_EstimateSizeOfExpr(expr->data.diadic.left, size, level); - if (size <= inline_max_size) - size = CInline_EstimateSizeOfExpr(expr->data.diadic.right, size, level) + 1; - break; - - case EFUNCCALL: - case EFUNCCALLP: - if ( - ENODE_IS(expr->data.funccall.funcref, EOBJREF) && - expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata && - CInline_CanExpand(expr->data.funccall.funcref) - ) - { - recursive_inline |= expr->data.funccall.funcref->data.objref == expanding_function; - if (level == 0) { - if (!recursive_inline) - size = inline_max_size + 1; - } else { - size = CInline_EstimateSizeOfFunc(expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata, size, level - 1); - } - } else { - size++; - } - - for (list = expr->data.funccall.args; list; list = list->next) { - if (size > inline_max_size) - break; - - size = CInline_EstimateSizeOfExpr(list->node, size, level); - } - break; - - case ECOND: - size = CInline_EstimateSizeOfExpr(expr->data.cond.cond, size, level); - if (size <= inline_max_size) - size = CInline_EstimateSizeOfExpr(expr->data.cond.expr1, size, level) + 1; - if (size <= inline_max_size) - size = CInline_EstimateSizeOfExpr(expr->data.cond.expr2, size, level) + 1; - break; - - case ENULLCHECK: - size = CInline_EstimateSizeOfExpr(expr->data.nullcheck.nullcheckexpr, size, level); - if (size <= inline_max_size) - size = CInline_EstimateSizeOfExpr(expr->data.nullcheck.condexpr, size, level) + 1; - break; - - case EMFPOINTER: - size = CInline_EstimateSizeOfExpr(expr->data.mfpointer.accessnode, size, level); - if (size <= inline_max_size) - size = CInline_EstimateSizeOfExpr(expr->data.mfpointer.mfpointer, size, level) + 1; - break; - - case EMEMBER: - if (expr->data.emember->expr) - size = CInline_EstimateSizeOfExpr(expr->data.emember->expr, size, level) + 1; - break; - - default: - size++; - } - - return size; -} - -static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 size, SInt32 level) { - CI_Statement *stmt; - SInt32 i; - - size += funcdata->numstatements; - if (size > inline_max_size) - return size; - - for (i = 0, stmt = funcdata->statements; i < funcdata->numstatements; i++, stmt++) { - switch (stmt->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - case ST_ASM: - break; - case ST_EXPRESSION: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - size = CInline_EstimateSizeOfExpr(stmt->u.expr, size, level); - break; - case ST_SWITCH: - size = CInline_EstimateSizeOfExpr(stmt->u.switchdata->expr, size, level); - break; - case ST_RETURN: - if (stmt->u.expr) - size = CInline_EstimateSizeOfExpr(stmt->u.expr, size, level); - break; - default: - CError_FATAL(1840); - } - - if (size > inline_max_size) - break; - } - - return size; -} - -static SInt32 EstimateExpandedSizeOfExpr(ENode *expr, SInt32 level) { - ENodeList *list; - SInt32 size; - - size = 0; - - switch (expr->type) { - ENODE_CASE_MONADIC: - size = EstimateExpandedSizeOfExpr(expr->data.monadic, level) + 1; - break; - - ENODE_CASE_DIADIC_ALL: - size = EstimateExpandedSizeOfExpr(expr->data.diadic.left, level) + 1; - size += EstimateExpandedSizeOfExpr(expr->data.diadic.right, level); - break; - - case EFUNCCALL: - case EFUNCCALLP: - if ( - ENODE_IS(expr->data.funccall.funcref, EOBJREF) && - expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata && - CInline_CanExpand(expr->data.funccall.funcref) - ) - { - if (level) { - SInt32 est = CInline_EstimateSizeOfFunc(expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata, size, level - 1); - if (est > inline_max_size) - size++; - else - size += est; - } else { - size++; - } - } else { - size++; - } - - for (list = expr->data.funccall.args; list; list = list->next) - size += EstimateExpandedSizeOfExpr(list->node, level); - break; - - case ECOND: - size = EstimateExpandedSizeOfExpr(expr->data.cond.cond, level) + 1; - size += EstimateExpandedSizeOfExpr(expr->data.cond.expr1, level); - size += EstimateExpandedSizeOfExpr(expr->data.cond.expr2, level); - break; - - case ENULLCHECK: - size = EstimateExpandedSizeOfExpr(expr->data.nullcheck.nullcheckexpr, level) + 1; - size += EstimateExpandedSizeOfExpr(expr->data.nullcheck.condexpr, level); - break; - - case EMFPOINTER: - size = EstimateExpandedSizeOfExpr(expr->data.mfpointer.accessnode, level) + 1; - size += EstimateExpandedSizeOfExpr(expr->data.mfpointer.mfpointer, level); - break; - - case EMEMBER: - if (expr->data.emember->expr) - size = EstimateExpandedSizeOfExpr(expr->data.emember->expr, level); - break; - - default: - size++; - } - - return size; -} - -static SInt32 EstimateExpandedSizeOfFunction(Statement *stmt) { - SInt32 size; - SInt32 level; - - level = copts.inlinelevel; - if (!level) - level = 8; - - size = 0; - - while (stmt) { - switch (stmt->type) { - case ST_NOP: - break; - case ST_EXPRESSION: - case ST_SWITCH: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - size++; - size += EstimateExpandedSizeOfExpr(stmt->expr, level); - break; - case ST_RETURN: - size++; - if (stmt->expr) - size = EstimateExpandedSizeOfExpr(stmt->expr, level); - break; - case ST_LABEL: - case ST_GOTO: - case ST_ASM: - size++; - break; - default: - CError_FATAL(2015); - } - - stmt = stmt->next; - } - - return size; -} - -static Boolean CInline_InlineFunctionCheck(ENode *expr) { - Object *object; - SInt32 level; - CI_FuncData *funcdata; - - object = expr->data.objref; - if (object->datatype == DALIAS) - object = object->u.alias.object; - - if ( - IS_TYPE_FUNC(object->type) && - ((object->qual & Q_INLINE) || (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_800)) && - (object->datatype == DFUNC || (object->datatype == DVFUNC && (expr->flags & ENODE_FLAG_80))) - ) - { - if (copts.alwaysinline) - return 1; - - if (copts.inline_bottom_up) { - if (!object->u.func.u.ifuncdata) - return 0; - - level = (copts.inlinelevel == 0) ? (7 - cinline_level) : (copts.inlinelevel - cinline_level - 1); - if ((object->qual & Q_INLINE) && level == 0) - return 1; - - if (CInline_EstimateSizeOfFunc(object->u.func.u.ifuncdata, 0, level) > inline_max_size) - return 0; - } else if (cinline_level > 0 && copts.inlinelevel == 0) { - funcdata = object->u.func.u.ifuncdata; - if (!funcdata) - return 0; - - if (funcdata->numstatements > 10) - return 0; - if (cinline_level > 1 && funcdata->numstatements > 7) - return 0; - if (cinline_level > 2 && funcdata->numstatements > 3) - return 0; - } - - return 1; - } else { - return 0; - } - - return 0; -} - -static ENode *CInline_ExpandExpression(ENode *expr) { - ENodeList *list; - Boolean save; - - switch (expr->type) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case ETYPCON: - case EBITFIELD: - expr->data.monadic = CInline_ExpandExpression(expr->data.monadic); - break; - - case EFORCELOAD: - expr->data.monadic = CInline_ExpandExpression(expr->data.monadic); - if (ENODE_IS(expr->data.monadic, EFORCELOAD)) - expr->data.monadic = expr->data.monadic->data.monadic; - break; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case EPMODULO: - case EROTL: - case EROTR: - expr->data.diadic.left = CInline_ExpandExpression(expr->data.diadic.left); - expr->data.diadic.right = CInline_ExpandExpression(expr->data.diadic.right); - break; - - case ELAND: - case ELOR: - case ECOMMA: - expr->data.diadic.left = CInline_ExpandExpression(expr->data.diadic.left); - save = cinline_unconditionalpart; - cinline_unconditionalpart = 0; - expr->data.diadic.right = CInline_ExpandExpression(expr->data.diadic.right); - cinline_unconditionalpart = save; - break; - - case EFUNCCALL: - case EFUNCCALLP: - expr->data.funccall.funcref = CInline_ExpandExpression(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - list->node = CInline_ExpandExpression(list->node); - - if (ENODE_IS(expr->data.funccall.funcref, EOBJREF) && CInline_InlineFunctionCheck(expr->data.funccall.funcref)) - expr = CInline_InlineFunctionExpression(expr); - break; - - case ENULLCHECK: - expr->data.nullcheck.nullcheckexpr = CInline_ExpandExpression(expr->data.nullcheck.nullcheckexpr); - save = cinline_unconditionalpart; - cinline_unconditionalpart = 0; - expr->data.nullcheck.condexpr = CInline_ExpandExpression(expr->data.nullcheck.condexpr); - cinline_unconditionalpart = save; - break; - - case EMFPOINTER: - expr->data.mfpointer.accessnode = CInline_ExpandExpression(expr->data.mfpointer.accessnode); - expr->data.mfpointer.mfpointer = CInline_ExpandExpression(expr->data.mfpointer.mfpointer); - break; - - case ECOND: - expr->data.cond.cond = CInline_ExpandExpression(expr->data.cond.cond); - save = cinline_unconditionalpart; - cinline_unconditionalpart = 0; - expr->data.cond.expr1 = CInline_ExpandExpression(expr->data.cond.expr1); - expr->data.cond.expr2 = CInline_ExpandExpression(expr->data.cond.expr2); - cinline_unconditionalpart = save; - break; - - case EMEMBER: - if (expr->data.emember->expr) - expr = CInline_ExpandExpression(expr->data.emember->expr); - else - expr = nullnode(); - break; - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ELABEL: - case EOBJLIST: - case EINSTRUCTION: - case EVECTOR128CONST: - break; - - default: - CError_FATAL(2235); - } - - return expr; -} - -static Statement *CInline_NewStatement(StatementType sttype) { - Statement *stmt = lalloc(sizeof(Statement)); - memclrw(stmt, sizeof(Statement)); - - stmt->type = sttype; - if (cinline_serial_stmt) - cinline_cur_serial_stmt->next = stmt; - else - cinline_serial_stmt = stmt; - cinline_cur_serial_stmt = stmt; - - return stmt; -} - -static ENode *CInline_LoadToTemp(ENode *expr, Object **objectptr) { - Object *object; - - object = *objectptr; - if (!object) { - switch (expr->rtype->type) { - case TYPEVOID: - return expr; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPESTRUCT: - case TYPECLASS: - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - object = create_temp_object(expr->rtype); - *objectptr = object; - break; - default: - CError_FATAL(2288); - } - } - - return makediadicnode(create_objectnode(object), expr, EASS); -} - -static ENode *CInline_SerializeEFORCELOAD(ENode *expr) { - Statement *stmt; - Object *temp = NULL; - - while (ENODE_IS(expr->data.monadic, EFORCELOAD)) { - expr->data.monadic = expr->data.monadic->data.monadic; - } - - expr->data.monadic = CInline_SerializeExpr(expr->data.monadic); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = CInline_LoadToTemp(expr->data.monadic, &temp); - return create_objectnode(temp); -} - -static ENode *CInline_SerializeECOMMA(ENode *expr) { - Statement *stmt; - - expr->data.diadic.left = CInline_SerializeExpr(expr->data.diadic.left); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = expr->data.diadic.left; - return CInline_SerializeExpr(expr->data.diadic.right); -} - -static ENode *CInline_SerializeELOR(ENode *expr) { - ENode *n; - Statement *stmt; - CLabel *label; - Object *temp = NULL; - - label = newlabel(); - - n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.left), ELOGNOT); - n->rtype = expr->rtype; - n = makemonadicnode(n, ELOGNOT); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_IFGOTO); - stmt->expr = n; - stmt->label = label; - - n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.right), ELOGNOT); - n->rtype = expr->rtype; - n = makemonadicnode(n, ELOGNOT); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = n; - - stmt = CInline_NewStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - return create_objectnode(temp); -} - -static ENode *CInline_SerializeELAND(ENode *expr) { - ENode *n; - Statement *stmt; - CLabel *label; - Object *temp = NULL; - - label = newlabel(); - - n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.left), ELOGNOT); - n->rtype = expr->rtype; - n = makemonadicnode(n, ELOGNOT); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_IFNGOTO); - stmt->expr = n; - stmt->label = label; - - n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.right), ELOGNOT); - n->rtype = expr->rtype; - n = makemonadicnode(n, ELOGNOT); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = n; - - stmt = CInline_NewStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - return create_objectnode(temp); -} - -static ENode *CInline_SerializeEPRECOMP(ENode *expr) { - UIDTemp *uidtemp; - - uidtemp = cinline_uid_temps; - while (1) { - if (!uidtemp) - CError_FATAL(2449); - if (uidtemp->uid == expr->data.precompid) - return create_objectnode(uidtemp->object); - uidtemp = uidtemp->next; - } -} - -static ENode *CInline_SerializeENULLCHECK(ENode *expr) { - Statement *stmt; - CLabel *label; - ENode *n; - Object *temp = NULL; - UIDTemp uidtemp; - - label = newlabel(); - - n = CInline_SerializeExpr(expr->data.nullcheck.nullcheckexpr); - stmt = CInline_NewStatement(ST_IFNGOTO); - stmt->expr = CInline_LoadToTemp(n, &temp); - stmt->label = label; - - uidtemp.next = cinline_uid_temps; - uidtemp.object = temp; - uidtemp.uid = expr->data.nullcheck.precompid; - cinline_uid_temps = &uidtemp; - - n = CInline_SerializeExpr(expr->data.nullcheck.condexpr); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = CInline_LoadToTemp(n, &temp); - - cinline_uid_temps = uidtemp.next; - - stmt = CInline_NewStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - return create_objectnode(temp); -} - -static ENode *CInline_SerializeECOND(ENode *expr) { - Statement *stmt; - CLabel *label1; - CLabel *label2; - ENode *n; - Object *temp = NULL; - - label1 = newlabel(); - label2 = newlabel(); - - n = CInline_SerializeExpr(expr->data.cond.cond); - stmt = CInline_NewStatement(ST_IFNGOTO); - stmt->expr = n; - stmt->label = label1; - - n = CInline_SerializeExpr(expr->data.cond.expr1); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = n; - - stmt = CInline_NewStatement(ST_GOTO); - stmt->label = label2; - - stmt = CInline_NewStatement(ST_LABEL); - stmt->label = label1; - label1->stmt = stmt; - - n = CInline_SerializeExpr(expr->data.cond.expr2); - n = CInline_LoadToTemp(n, &temp); - stmt = CInline_NewStatement(ST_EXPRESSION); - stmt->expr = n; - - stmt = CInline_NewStatement(ST_LABEL); - stmt->label = label2; - label2->stmt = stmt; - - if (!temp) { - n = nullnode(); - n->rtype = &stvoid; - return n; - } - - return create_objectnode(temp); -} - -static ENode *CInline_SerializeExpr(ENode *expr) { - ENodeList *list; - - switch (expr->type) { - case EFORCELOAD: - return CInline_SerializeEFORCELOAD(expr); - case ECOMMA: - return CInline_SerializeECOMMA(expr); - case ELAND: - return CInline_SerializeELAND(expr); - case ELOR: - return CInline_SerializeELOR(expr); - case EPRECOMP: - return CInline_SerializeEPRECOMP(expr); - case ENULLCHECK: - return CInline_SerializeENULLCHECK(expr); - case ECOND: - return CInline_SerializeECOND(expr); - - case EINITTRYCATCH: - expr->data.itc.initexpr = CInline_SerializeExpr(expr->data.itc.initexpr); - expr->data.itc.tryexpr = CInline_SerializeExpr(expr->data.itc.tryexpr); - expr->data.itc.catchexpr = CInline_SerializeExpr(expr->data.itc.catchexpr); - expr->data.itc.result = CInline_SerializeExpr(expr->data.itc.result); - return expr; - - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case ETYPCON: - case EBITFIELD: - expr->data.monadic = CInline_SerializeExpr(expr->data.monadic); - return expr; - - case EMUL: - case EDIV: - case EMODULO: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case EPMODULO: - case EROTL: - case EROTR: - expr->data.diadic.left = CInline_SerializeExpr(expr->data.diadic.left); - expr->data.diadic.right = CInline_SerializeExpr(expr->data.diadic.right); - return expr; - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case ELABEL: - case EOBJLIST: - case EINSTRUCTION: - case EVECTOR128CONST: - return expr; - - case EFUNCCALL: - case EFUNCCALLP: - expr->data.funccall.funcref = CInline_SerializeExpr(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - list->node = CInline_SerializeExpr(list->node); - return expr; - - case EMFPOINTER: - // bug??? - expr->data.mfpointer.accessnode = CInline_SerializeExpr(expr->data.mfpointer.accessnode); - expr->data.mfpointer.accessnode = CInline_SerializeExpr(expr->data.mfpointer.mfpointer); - return expr; - - case EMEMBER: - if (expr->data.emember->expr) - return CInline_SerializeExpr(expr->data.emember->expr); - return expr; - - default: - CError_FATAL(2684); - return expr; - } -} - -void CInline_SerializeStatement(Statement *stmt) { - Statement *scan; - Statement *copy; - - cinline_serial_stmt = NULL; - cinline_uid_temps = NULL; - stmt->expr = CInline_SerializeExpr(stmt->expr); - - if (cinline_serial_stmt) { - for (scan = cinline_serial_stmt; scan; scan = scan->next) { - scan->value = stmt->value; - scan->dobjstack = stmt->dobjstack; - scan->sourceoffset = stmt->sourceoffset; - scan->sourcefilepath = stmt->sourcefilepath; - } - - copy = CInline_NewStatement(ST_EXPRESSION); - *copy = *stmt; - - *stmt = *cinline_serial_stmt; - } -} - -static void CInline_UnpackSwitch(Statement *stmt, CI_Statement *packstmt, CLabel **labels) { - SwitchInfo *info; - SwitchCase *swcase; - short i; - - info = lalloc(sizeof(SwitchInfo)); - stmt->label = (CLabel *) info; - CError_ASSERT(2730, info->defaultlabel = labels[packstmt->u.switchdata->defaultlabelID]); - info->x8 = packstmt->u.switchdata->unkSwitch8; - - for (i = 0; i < packstmt->u.switchdata->numcases; i++) { - if (i == 0) { - swcase = lalloc(sizeof(SwitchCase)); - info->cases = swcase; - } else { - swcase->next = lalloc(sizeof(SwitchCase)); - swcase = swcase->next; - } - - swcase->next = NULL; - swcase->min = packstmt->u.switchdata->cases[i].min; - swcase->max = packstmt->u.switchdata->cases[i].max; - CError_ASSERT(2740, swcase->label = labels[packstmt->u.switchdata->cases[i].labelID]); - } -} - -Object *CInline_GetLocalObj(SInt32 id, Boolean flag) { - ObjectList *list; - - if (id) { - if (id & 0x80000000) { - id = (id & 0x7FFFFFFF) - 1; - if (flag) { - CError_ASSERT(2761, local_aobjects[id].object); - return local_aobjects[id].object; - } - - for (list = arguments; list; list = list->next, id--) { - if (id == 0) - return list->object; - } - - CError_FATAL(2765); - } else { - id--; - if (flag) { - CError_ASSERT(2772, local_dobjects[id]); - return local_dobjects[id]; - } - - for (list = locals; list; list = list->next, id--) { - if (id == 0) - return list->object; - } - - CError_FATAL(2776); - } - } - - return NULL; -} - -static ExceptionAction *CInline_UnpackActions(CI_Statement *packstmt, Boolean flag) { - ExceptionAction *packexc; - ExceptionAction *last; - ExceptionAction *exc; - - packexc = packstmt->dobjstack; - last = NULL; - - while (packexc) { - exc = galloc(sizeof(ExceptionAction)); - exc->prev = last; - last = exc; - - exc->type = packexc->type; - - switch (packexc->type) { - case EAT_DESTROYLOCAL: - exc->data.destroy_local.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local.local, flag); - exc->data.destroy_local.dtor = packexc->data.destroy_local.dtor; - break; - case EAT_DESTROYLOCALCOND: - exc->data.destroy_local_cond.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_cond.local, flag); - exc->data.destroy_local_cond.dtor = packexc->data.destroy_local_cond.dtor; - exc->data.destroy_local_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_cond.cond, flag); - break; - case EAT_DESTROYLOCALOFFSET: - exc->data.destroy_local_offset.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_offset.local, flag); - exc->data.destroy_local_offset.dtor = packexc->data.destroy_local_offset.dtor; - exc->data.destroy_local_offset.offset = packexc->data.destroy_local_offset.offset; - break; - case EAT_DESTROYLOCALPOINTER: - exc->data.destroy_local_pointer.pointer = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_pointer.pointer, flag); - exc->data.destroy_local_pointer.dtor = packexc->data.destroy_local_pointer.dtor; - break; - case EAT_DESTROYLOCALARRAY: - exc->data.destroy_local_array.localarray = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_array.localarray, flag); - exc->data.destroy_local_array.dtor = packexc->data.destroy_local_array.dtor; - exc->data.destroy_local_array.elements = packexc->data.destroy_local_array.elements; - exc->data.destroy_local_array.element_size = packexc->data.destroy_local_array.element_size; - break; - case EAT_DESTROYPARTIALARRAY: - exc->data.destroy_partial_array.arraypointer = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.arraypointer, flag); - exc->data.destroy_partial_array.arraycounter = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.arraycounter, flag); - exc->data.destroy_partial_array.dtor = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.dtor, flag); - exc->data.destroy_partial_array.element_size = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.element_size, flag); - break; - case EAT_DESTROYMEMBER: - case EAT_DESTROYBASE: - exc->data.destroy_member.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member.objectptr, flag); - exc->data.destroy_member.dtor = packexc->data.destroy_member.dtor; - exc->data.destroy_member.offset = packexc->data.destroy_member.offset; - break; - case EAT_DESTROYMEMBERCOND: - exc->data.destroy_member_cond.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_cond.objectptr, flag); - exc->data.destroy_member_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_cond.cond, flag); - exc->data.destroy_member_cond.dtor = packexc->data.destroy_member_cond.dtor; - exc->data.destroy_member_cond.offset = packexc->data.destroy_member_cond.offset; - break; - case EAT_DESTROYMEMBERARRAY: - exc->data.destroy_member_array.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_array.objectptr, flag); - exc->data.destroy_member_array.dtor = packexc->data.destroy_member_array.dtor; - exc->data.destroy_member_array.offset = packexc->data.destroy_member_array.offset; - exc->data.destroy_member_array.elements = packexc->data.destroy_member_array.elements; - exc->data.destroy_member_array.element_size = packexc->data.destroy_member_array.element_size; - break; - case EAT_DELETEPOINTER: - case EAT_DELETELOCALPOINTER: - exc->data.delete_pointer.pointerobject = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer.pointerobject, flag); - exc->data.delete_pointer.deletefunc = packexc->data.delete_pointer.deletefunc; - break; - case EAT_DELETEPOINTERCOND: - exc->data.delete_pointer_cond.pointerobject = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer_cond.pointerobject, flag); - exc->data.delete_pointer_cond.deletefunc = packexc->data.delete_pointer_cond.deletefunc; - exc->data.delete_pointer_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer_cond.cond, flag); - break; - case EAT_CATCHBLOCK: { - LabelTrans *trans; - exc->data.catch_block.catch_object = CInline_GetLocalObj((SInt32) packexc->data.catch_block.catch_object, flag); - exc->data.catch_block.catch_info_object = CInline_GetLocalObj((SInt32) packexc->data.catch_block.catch_info_object, flag); - - trans = lalloc(sizeof(LabelTrans)); - trans->next = cinline_label_trans; - cinline_label_trans = trans; - - trans->id = (SInt32) packexc->data.catch_block.catch_label; - trans->labelptr = &exc->data.catch_block.catch_label; - - exc->data.catch_block.catch_typeid = packexc->data.catch_block.catch_typeid; - exc->data.catch_block.catch_type = packexc->data.catch_block.catch_type; - exc->data.catch_block.catch_qual = packexc->data.catch_block.catch_qual; - break; - } - case EAT_ACTIVECATCHBLOCK: - exc->data.active_catch_block.catch_info_object = CInline_GetLocalObj((SInt32) packexc->data.active_catch_block.catch_info_object, flag); - break; - case EAT_SPECIFICATION: { - LabelTrans *trans; - exc->data.specification.unexp_ids = packexc->data.specification.unexp_ids; - exc->data.specification.unexp_id = packexc->data.specification.unexp_id; - - trans = lalloc(sizeof(LabelTrans)); - trans->next = cinline_label_trans; - cinline_label_trans = trans; - - trans->id = (SInt32) packexc->data.specification.unexp_label; - trans->labelptr = &exc->data.specification.unexp_label; - - exc->data.specification.unexp_info_object = CInline_GetLocalObj((SInt32) packexc->data.specification.unexp_info_object, flag); - break; - } - case EAT_TERMINATE: - break; - default: - CError_FATAL(2904); - } - - packexc = packexc->prev; - } - - return last; -} - -static Statement *CInline_ExpandStatements(Object *funcobj, Statement *stmt, CI_FuncData *funcdata, ENode *funccall, CLabel *label, Object *resultobj, Boolean flag) { - CLabel **labels; - CI_Statement *packstmt; - short i; - CI_StmtLink *stmtLinks; - CI_StmtLink *link; - ENode *setupArgs; - Boolean is_result_class_1; - Statement origStmt; - - origStmt = *stmt; - is_result_class_1 = CMach_GetFunctionResultClass(TYPE_FUNC(funcobj->type)) == 1; - - if ((setupArgs = CInline_SetupArgsExpression(funcobj, funcdata, funccall->data.funccall.args))) { - stmt->type = ST_EXPRESSION; - stmt->expr = CInline_FoldConst(setupArgs); - } else { - stmt->type = ST_NOP; - } - - stmtLinks = NULL; - cinline_label_trans = NULL; - - labels = lalloc(sizeof(CLabel *) * funcdata->numstatements); - memclrw(labels, sizeof(CLabel *) * funcdata->numstatements); - - for (i = 0, packstmt = funcdata->statements; i < funcdata->numstatements; i++, packstmt++) { - stmt->next = lalloc(sizeof(Statement)); - stmt = stmt->next; - *stmt = origStmt; - - stmt->type = packstmt->type; - stmt->flags = packstmt->flags; - stmt->value += packstmt->value; - - if (packstmt->dobjstack) { - ExceptionAction *unpacked = CInline_UnpackActions(packstmt, 1); - if (stmt->dobjstack) { - ExceptionAction *scan = unpacked; - while (scan->prev) - scan = scan->prev; - scan->prev = stmt->dobjstack; - } - stmt->dobjstack = unpacked; - } - - switch (stmt->type) { - case ST_NOP: - break; - - case ST_EXPRESSION: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.expr, CopyMode4)); - break; - - case ST_RETURN: - if (packstmt->u.expr) { - stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.expr, CopyMode4)); - if (is_result_class_1) - stmt->expr = makecommaexpression(stmt->expr, CInline_ReturnMemResult(funcobj)); - - if (resultobj) { - stmt->type = ST_EXPRESSION; - stmt->expr = makediadicnode(create_objectnode2(resultobj), stmt->expr, EASS); - } else { - stmt->type = origStmt.type; - if (stmt->type == ST_EXPRESSION && !CInline_ExpressionHasSideEffect(stmt->expr)) - stmt->type = ST_NOP; - } - - if (label) { - stmt->next = lalloc(sizeof(Statement)); - stmt = stmt->next; - *stmt = origStmt; - stmt->type = ST_GOTO; - stmt->label = label; - } - } else { - if (label) { - stmt->type = ST_GOTO; - stmt->label = label; - } else { - stmt->type = ST_NOP; - } - } - break; - - case ST_LABEL: - labels[i] = stmt->label = newlabel(); - stmt->label->stmt = stmt; - break; - - case ST_IFGOTO: - case ST_IFNGOTO: - stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.ifgoto.expr, CopyMode4)); - case ST_GOTO: - link = lalloc(sizeof(CI_StmtLink)); - link->next = stmtLinks; - stmtLinks = link; - - link->stmt = stmt; - link->ciStmt = packstmt; - break; - - case ST_SWITCH: - stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.switchdata->expr, CopyMode4)); - case ST_ASM: - link = lalloc(sizeof(CI_StmtLink)); - link->next = stmtLinks; - stmtLinks = link; - - link->stmt = stmt; - link->ciStmt = packstmt; - break; - - default: - CError_FATAL(3040); - } - } - - if (label) { - stmt->next = lalloc(sizeof(Statement)); - stmt = stmt->next; - *stmt = origStmt; - - stmt->type = ST_LABEL; - stmt->label = label; - label->stmt = stmt; - - if (flag) { - stmt->next = lalloc(sizeof(Statement)); - stmt = stmt->next; - *stmt = origStmt; - } - } - - while (stmtLinks) { - Statement *linkstmt = stmtLinks->stmt; - packstmt = stmtLinks->ciStmt; - - switch (linkstmt->type) { - case ST_GOTO: - CError_ASSERT(3060, linkstmt->label = labels[packstmt->u.statementnum]); - break; - case ST_IFGOTO: - case ST_IFNGOTO: - CError_ASSERT(3065, linkstmt->label = labels[packstmt->u.ifgoto.statementnum]); - break; - case ST_SWITCH: - CInline_UnpackSwitch(linkstmt, packstmt, labels); - break; - case ST_ASM: - InlineAsm_UnpackAsmStatement(linkstmt, labels, 1, packstmt->u.asmdata.data, packstmt->u.asmdata.size); - break; - default: - CError_FATAL(3076); - } - - stmtLinks = stmtLinks->next; - } - - while (cinline_label_trans) { - CError_ASSERT(3083, *cinline_label_trans->labelptr = labels[cinline_label_trans->id]); - cinline_label_trans = cinline_label_trans->next; - } - - return stmt; -} - -static Statement *CInline_InlineFunctionStatement(Statement *stmt, Boolean *changed) { - Object *object; - CI_FuncData *funcdata; - CLabel *label; - - *changed = 0; - - object = stmt->expr->data.funccall.funcref->data.objref; - if (object->datatype == DALIAS) - object = object->u.alias.object; - - funcdata = object->u.func.u.ifuncdata; - if (!funcdata || funcdata->can_inline < CI_CanInline3) - return stmt; - - if (stmt->type != ST_EXPRESSION) { - short i; - for (i = 0; i < (funcdata->numstatements - 1); i++) { - if (funcdata->statements[i].type == ST_RETURN) - return stmt; - } - - if (funcdata->statements[funcdata->numstatements - 1].type != ST_RETURN) - return stmt; - - label = NULL; - } else { - label = newlabel(); - } - - *changed = 1; - return CInline_ExpandStatements(object, stmt, funcdata, stmt->expr, label, NULL, 0); -} - -static Statement *CInline_ExtractInlineFunction(Statement *stmt) { - ENode *expr; - CI_FuncData *funcdata; - short i; - Object *funcObject; - Object *resultObject; - - for (i = 0; i < cinline_stmtlevelexprs; i++) { - expr = cinline_stmtlevelexpr[i]; - - funcObject = expr->data.funccall.funcref->data.objref; - if (funcObject->datatype == DALIAS) - funcObject = funcObject->u.alias.object; - - if ((funcdata = funcObject->u.func.u.ifuncdata)) { - TypeFunc *tfunc = TYPE_FUNC(funcObject->type); - CError_ASSERT(3141, IS_TYPE_FUNC(tfunc)); - - if (!IS_TYPE_VOID(tfunc->functype)) { - if (CMach_GetFunctionResultClass(TYPE_FUNC(funcObject->type)) == 1) - resultObject = CInline_NewLocalObject(CDecl_NewPointerType(tfunc->functype), 0, 0, 0); - else - resultObject = CInline_NewLocalObject(tfunc->functype, 0, 0, 0); - } else { - resultObject = NULL; - } - - stmt = CInline_ExpandStatements(funcObject, stmt, funcdata, expr, newlabel(), resultObject, 1); - - if (resultObject) - *expr = *create_objectnode2(resultObject); - else - *expr = *nullnode(); - } - } - - return stmt; -} - -static Statement *CInline_ExpandStatement(Statement *stmt) { - Boolean changed; - - do { - changed = 0; - - if ( - stmt->type == ST_EXPRESSION && - ENODE_IS(stmt->expr, EINDIRECT) && - !CParser_IsVolatile(stmt->expr->rtype, ENODE_QUALS(stmt->expr)) - ) - { - stmt->expr = stmt->expr->data.monadic; - changed = 1; - if (ENODE_IS2(stmt->expr, EOBJREF, EBITFIELD)) - stmt->expr = nullnode(); - } - - if (ENODE_IS(stmt->expr, ECOMMA)) { - Statement *newStmt = lalloc(sizeof(Statement)); - *newStmt = *stmt; - - stmt->next = newStmt; - stmt->type = ST_EXPRESSION; - stmt->expr = stmt->expr->data.diadic.left; - newStmt->expr = newStmt->expr->data.diadic.right; - - changed = 1; - } - } while (changed); - - if ( - ENODE_IS2(stmt->expr, EFUNCCALL, EFUNCCALLP) && - ENODE_IS(stmt->expr->data.funccall.funcref, EOBJREF) && - CInline_InlineFunctionCheck(stmt->expr->data.funccall.funcref) - ) - { - stmt = CInline_InlineFunctionStatement(stmt, &changed); - if (changed) { - any_inline_expanded = 1; - return stmt; - } - } - - inline_expanded = 0; - cinline_unconditionalpart = 1; - cinline_serialize_stmt = 0; - cinline_stmtlevelexprs = 0; - stmt->expr = CInline_ExpandExpression(stmt->expr); - - if (cinline_serialize_stmt) { - cinline_unconditionalpart = 1; - cinline_serialize_stmt = 0; - cinline_stmtlevelexprs = 0; - CInline_SerializeStatement(stmt); - stmt->expr = CInline_ExpandExpression(stmt->expr); - } - - if (inline_expanded) { - stmt->expr = CInline_FoldConst(stmt->expr); - any_inline_expanded = 1; - } - - if (cinline_stmtlevelexprs) { - stmt = CInline_ExtractInlineFunction(stmt); - any_inline_expanded = 1; - } - - return stmt; -} - -static void CInline_ForceReverseSearch(ENode *) { - cinline_funccallfound = 1; -} - -static ENode *CInline_ForceReverseEvaluation(ENode *expr) { - ENode *commanodes; - ENodeList *list; - int counter; - ENode *ass; - ENode *inner; - ENode *copy; - - list = expr->data.funccall.args; - counter = 0; - commanodes = NULL; - - while (list) { - cinline_funccallfound = 0; - inner = list->node; - CExpr_SearchExprTree(inner, CInline_ForceReverseSearch, 2, EFUNCCALL, EFUNCCALLP); - - if (cinline_funccallfound && ++counter > 0) { - inner = create_objectrefnode(create_temp_object(inner->rtype)); - copy = lalloc(sizeof(ENode)); - *copy = *inner; - - copy = makemonadicnode(copy, EINDIRECT); - copy->rtype = TPTR_TARGET(copy->rtype); - - inner = makemonadicnode(inner, EINDIRECT); - inner->rtype = TPTR_TARGET(inner->rtype); - - ass = makediadicnode(inner, copy, EASS); - list->node = copy; - - if (commanodes) - commanodes = makediadicnode(ass, commanodes, ECOMMA); - else - commanodes = ass; - } - - list = list->next; - } - - if (commanodes) { - commanodes = makediadicnode(commanodes, expr, ECOMMA); - commanodes->rtype = expr->rtype; - return commanodes; - } - - return expr; -} - -static void CInline_ExportCheck(ENode *expr) { - while (1) { - switch (expr->type) { - case EOBJREF: - CInline_ObjectAddrRef(expr->data.objref); - if (expr->data.objref->datatype == DALIAS) { - CExpr_AliasTransform(expr); - continue; - } - return; - - ENODE_CASE_MONADIC: - expr = expr->data.monadic; - continue; - - ENODE_CASE_DIADIC_ALL: - CInline_ExportCheck(expr->data.diadic.left); - expr = expr->data.diadic.right; - continue; - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EPRECOMP: - case EINSTRUCTION: - case EVECTOR128CONST: - return; - - case ELABEL: - if (expr->data.label->stmt) - expr->data.label->stmt->flags |= StmtFlag_1; - return; - - case EFUNCCALL: - case EFUNCCALLP: { - ENodeList *list; - TypeClass *tclass; - SInt32 index; - - for (list = expr->data.funccall.args; list; list = list->next) - CInline_ExportCheck(list->node); - - expr = expr->data.funccall.funcref; - if ( - copts.warn_notinlined && - !copts.dontinline && - ENODE_IS(expr, EOBJREF) && - (expr->data.objref->qual & Q_INLINE) && - expr->data.objref->datatype != DINLINEFUNC && - !CParser_IsVirtualFunction(expr->data.objref, &tclass, &index) - ) - CError_Warning(CErrorStr342, expr->data.objref); - - continue; - } - - case ENULLCHECK: - CInline_ExportCheck(expr->data.nullcheck.nullcheckexpr); - expr = expr->data.nullcheck.condexpr; - continue; - - case EMFPOINTER: - *expr = *nullnode(); - continue; - - case ECOND: - CInline_ExportCheck(expr->data.cond.cond); - CInline_ExportCheck(expr->data.cond.expr1); - expr = expr->data.cond.expr2; - continue; - - case EMEMBER: - if (expr->data.emember->expr) { - *expr = *expr->data.emember->expr; - continue; - } - case EOBJLIST: - *expr = *nullnode(); - continue; - - default: - CError_FATAL(3372); - } - } -} - -static void CInline_Expand(Statement *stmt) { - Statement *scan; - - if (!copts.dontinline && copts.inlinelevel >= 0) { - if (copts.inline_bottom_up) { - inline_max_size = copts.inlinemaxsize; - while (inline_max_size > 1 && EstimateExpandedSizeOfFunction(stmt) > copts.inlinemaxtotalsize) - inline_max_size >>= 1; - } - - cinline_level = 0; - while (1) { - any_inline_expanded = 0; - for (scan = stmt; scan; scan = scan->next) { - switch (scan->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_ASM: - break; - case ST_RETURN: - if (!scan->expr) - break; - case ST_EXPRESSION: - case ST_SWITCH: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_GOTOEXPR: - scan = CInline_ExpandStatement(scan); - break; - default: - CError_FATAL(3438); - } - } - - if (!copts.inline_bottom_up && !any_inline_expanded) - break; - - if (!copts.alwaysinline || copts.inline_bottom_up) { - if (copts.inlinelevel == 0) { - if (copts.inline_bottom_up) { - if ((cinline_level + 1) >= 8) - break; - } else { - if (cinline_level >= 3) - break; - } - } else { - if ((cinline_level + 1) >= copts.inlinelevel) - break; - } - } - - if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) - CError_UserBreak(); - - cinline_level++; - } - } - - while (stmt) { - if (stmt->dobjstack) - CExcept_CheckStackRefs(stmt->dobjstack); - - switch (stmt->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_ASM: - break; - case ST_RETURN: - if (!stmt->expr) - break; - case ST_EXPRESSION: - case ST_SWITCH: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_GOTOEXPR: - CInline_ExportCheck(stmt->expr); - break; - default: - CError_FATAL(3501); - } - - stmt = stmt->next; - } -} - -SInt16 CInline_GetStatementNumber(Statement *first, Statement *stmt) { - SInt16 number = 0; - - while (first) { - if (first == stmt) - return number; - - first = first->next; - number++; - } - - CError_FATAL(3517); - return 0; -} - -static CI_Switch *CInline_PackSwitch(Statement *start, Statement *stmt) { - SwitchInfo *info; - SwitchCase *swcase; - short numcases; - CI_Switch *packed; - - info = (SwitchInfo *) stmt->label; - swcase = info->cases; - numcases = 0; - while (swcase) { - swcase = swcase->next; - numcases++; - } - - packed = galloc(sizeof(CI_Switch) + numcases * sizeof(CI_SwitchCase)); - packed->expr = CInline_CopyExpression(stmt->expr, CopyMode2); - packed->defaultlabelID = CInline_GetStatementNumber(start, info->defaultlabel->stmt); - packed->unkSwitch8 = info->x8; - packed->numcases = numcases; - - for (swcase = info->cases, numcases = 0; swcase; swcase = swcase->next, numcases++) { - packed->cases[numcases].labelID = CInline_GetStatementNumber(start, swcase->label->stmt); - packed->cases[numcases].min = swcase->min; - packed->cases[numcases].max = swcase->max; - } - - return packed; -} - -static UInt8 CInline_CanInline(Object *object, Statement *stmt) { - UInt8 resultClass; - FuncArg *arg; - UInt8 result; - - resultClass = CMach_GetFunctionResultClass(TYPE_FUNC(object->type)); - if ( - resultClass && - (resultClass != 1 || (IS_TYPE_CLASS(TYPE_FUNC(object->type)->functype) && CClass_Destructor(TYPE_CLASS(TYPE_FUNC(object->type)->functype)))) - ) - return CI_CanInline0; - - for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) { - if (arg == &elipsis) - return CI_CanInline0; - if (arg == &oldstyle) - break; - - if (IS_TYPE_CLASS(arg->type) && CClass_Destructor(TYPE_CLASS(arg->type))) - return CI_CanInline0; - } - - result = CI_CanInline6; - - while (stmt) { - if (stmt->dobjstack) - return CI_CanInline3; - - switch (stmt->type) { - case ST_EXPRESSION: - break; - case ST_RETURN: - if (stmt->next || (stmt->expr == NULL && TYPE_FUNC(object->type)->functype != &stvoid)) - result = CI_CanInline3; - break; - default: - result = CI_CanInline3; - } - - stmt = stmt->next; - } - - return result; -} - -static ExceptionAction *CInline_PackActions(Statement *start, Statement *stmt) { - ExceptionAction *exc; - ExceptionAction *last; - ExceptionAction *packexc; - - exc = stmt->dobjstack; - last = NULL; - - while (exc) { - packexc = galloc(sizeof(ExceptionAction)); - packexc->prev = last; - last = packexc; - - packexc->type = exc->type; - - switch (exc->type) { - case EAT_DESTROYLOCAL: - packexc->data.destroy_local.local = (void *) CInline_GetLocalID(exc->data.destroy_local.local); - packexc->data.destroy_local.dtor = exc->data.destroy_local.dtor; - break; - case EAT_DESTROYLOCALCOND: - packexc->data.destroy_local_cond.local = (void *) CInline_GetLocalID(exc->data.destroy_local_cond.local); - packexc->data.destroy_local_cond.dtor = exc->data.destroy_local_cond.dtor; - packexc->data.destroy_local_cond.cond = (void *) CInline_GetLocalID(exc->data.destroy_local_cond.cond); - break; - case EAT_DESTROYLOCALOFFSET: - packexc->data.destroy_local_offset.local = (void *) CInline_GetLocalID(exc->data.destroy_local_offset.local); - packexc->data.destroy_local_offset.dtor = exc->data.destroy_local_offset.dtor; - packexc->data.destroy_local_offset.offset = exc->data.destroy_local_offset.offset; - break; - case EAT_DESTROYLOCALPOINTER: - packexc->data.destroy_local_pointer.pointer = (void *) CInline_GetLocalID(exc->data.destroy_local_pointer.pointer); - packexc->data.destroy_local_pointer.dtor = exc->data.destroy_local_pointer.dtor; - break; - case EAT_DESTROYLOCALARRAY: - packexc->data.destroy_local_array.localarray = (void *) CInline_GetLocalID(exc->data.destroy_local_array.localarray); - packexc->data.destroy_local_array.dtor = exc->data.destroy_local_array.dtor; - packexc->data.destroy_local_array.elements = exc->data.destroy_local_array.elements; - packexc->data.destroy_local_array.element_size = exc->data.destroy_local_array.element_size; - break; - case EAT_DESTROYPARTIALARRAY: - packexc->data.destroy_partial_array.arraypointer = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.arraypointer); - packexc->data.destroy_partial_array.arraycounter = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.arraycounter); - packexc->data.destroy_partial_array.dtor = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.dtor); - packexc->data.destroy_partial_array.element_size = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.element_size); - break; - case EAT_DESTROYMEMBER: - case EAT_DESTROYBASE: - packexc->data.destroy_member.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member.objectptr); - packexc->data.destroy_member.dtor = exc->data.destroy_member.dtor; - packexc->data.destroy_member.offset = exc->data.destroy_member.offset; - break; - case EAT_DESTROYMEMBERCOND: - packexc->data.destroy_member_cond.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member_cond.objectptr); - packexc->data.destroy_member_cond.cond = (void *) CInline_GetLocalID(exc->data.destroy_member_cond.cond); - packexc->data.destroy_member_cond.dtor = exc->data.destroy_member_cond.dtor; - packexc->data.destroy_member_cond.offset = exc->data.destroy_member_cond.offset; - break; - case EAT_DESTROYMEMBERARRAY: - packexc->data.destroy_member_array.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member_array.objectptr); - packexc->data.destroy_member_array.dtor = exc->data.destroy_member_array.dtor; - packexc->data.destroy_member_array.offset = exc->data.destroy_member_array.offset; - packexc->data.destroy_member_array.elements = exc->data.destroy_member_array.elements; - packexc->data.destroy_member_array.element_size = exc->data.destroy_member_array.element_size; - break; - case EAT_DELETEPOINTER: - case EAT_DELETELOCALPOINTER: - packexc->data.delete_pointer.pointerobject = (void *) CInline_GetLocalID(exc->data.delete_pointer.pointerobject); - packexc->data.delete_pointer.deletefunc = exc->data.delete_pointer.deletefunc; - break; - case EAT_DELETEPOINTERCOND: - packexc->data.delete_pointer_cond.pointerobject = (void *) CInline_GetLocalID(exc->data.delete_pointer_cond.pointerobject); - packexc->data.delete_pointer_cond.deletefunc = exc->data.delete_pointer_cond.deletefunc; - packexc->data.delete_pointer_cond.cond = (void *) CInline_GetLocalID(exc->data.delete_pointer_cond.cond); - break; - case EAT_CATCHBLOCK: - packexc->data.catch_block.catch_object = (void *) CInline_GetLocalID(exc->data.catch_block.catch_object); - packexc->data.catch_block.catch_info_object = (void *) CInline_GetLocalID(exc->data.catch_block.catch_info_object); - packexc->data.catch_block.catch_label = (void *) CInline_GetStatementNumber(start->next, exc->data.catch_block.catch_label->stmt); - packexc->data.catch_block.catch_typeid = exc->data.catch_block.catch_typeid; - packexc->data.catch_block.catch_type = exc->data.catch_block.catch_type; - packexc->data.catch_block.catch_qual = exc->data.catch_block.catch_qual; - break; - case EAT_ACTIVECATCHBLOCK: - packexc->data.active_catch_block.catch_info_object = (void *) CInline_GetLocalID(exc->data.active_catch_block.catch_info_object); - packexc->data.active_catch_block.call_dtor = exc->data.active_catch_block.call_dtor; - break; - case EAT_SPECIFICATION: - packexc->data.specification.unexp_ids = exc->data.specification.unexp_ids; - packexc->data.specification.unexp_id = exc->data.specification.unexp_id; - packexc->data.specification.unexp_label = (void *) CInline_GetStatementNumber(start->next, exc->data.specification.unexp_label->stmt); - packexc->data.specification.unexp_info_object = (void *) CInline_GetLocalID(exc->data.specification.unexp_info_object); - break; - case EAT_TERMINATE: - break; - default: - CError_FATAL(3720); - } - - exc = exc->prev; - } - - return last; -} - -void CInline_PackIFunctionData(CI_FuncData *funcdata, Statement *stmt, Object *object) { - ObjectList *list; - CI_Var *var; - Statement *scan; - CI_Statement *packstmt; - int i; - - cinline_first_stmt = stmt->next; - memclrw(funcdata, sizeof(CI_FuncData)); - - funcdata->can_inline = CInline_CanInline(object, stmt->next); - - if (copts.filesyminfo) { - funcdata->fileoffset = cparser_fileoffset; - funcdata->fileoffset.is_inline = 1; - funcdata->symdecloffset = symdecloffset; - funcdata->functionbodyoffset = functionbodyoffset; - funcdata->functionbodypath = functionbodypath; - funcdata->symdeclend = symdeclend; - } - - list = arguments; - i = 0; - while (list) { - list = list->next; - i++; - } - - if ((funcdata->numarguments = i) > 0) { - loc_args = funcdata->arguments = galloc(sizeof(CI_Var) * i); - memclrw(funcdata->arguments, sizeof(CI_Var) * i); - - for (list = arguments, var = funcdata->arguments; list; list = list->next, var++) { - var->name = list->object->name; - var->type = list->object->type; - var->qual = list->object->qual; - var->sflags = CInline_GetObjectSFlags(list->object); - var->xD = 0; - var->xE = 1; - } - } - - list = locals; - i = 0; - while (list) { - if (list->object->datatype == DLOCAL) - i++; - list = list->next; - } - - if ((funcdata->numlocals = i) > 0) { - loc_vars = funcdata->locals = galloc(sizeof(CI_Var) * i); - memclrw(funcdata->locals, sizeof(CI_Var) * i); - - for (list = locals, var = funcdata->locals; list; list = list->next) { - if (list->object->datatype == DLOCAL) { - var->name = list->object->name; - var->type = list->object->type; - var->qual = list->object->qual; - var->sflags = CInline_GetObjectSFlags(list->object); - var->xD = 0; - var->xE = 0; - var++; - } - } - } - - scan = stmt->next; - i = 0; - while (scan) { - scan = scan->next; - i++; - } - - funcdata->numstatements = i; - funcdata->statements = galloc(sizeof(CI_Statement) * i); - - for (scan = stmt->next, packstmt = funcdata->statements; scan; scan = scan->next, packstmt++) { - packstmt->type = scan->type; - packstmt->flags = scan->flags; - packstmt->value = scan->value; - packstmt->dobjstack = CInline_PackActions(stmt, scan); - packstmt->sourceoffset = scan->sourceoffset; - packstmt->sourcefilepath = scan->sourcefilepath; - - switch (scan->type) { - case ST_NOP: - case ST_LABEL: - break; - case ST_EXPRESSION: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - packstmt->u.expr = CInline_CopyExpression(scan->expr, CopyMode2); - break; - case ST_RETURN: - if (scan->expr) - packstmt->u.expr = CInline_CopyExpression(scan->expr, CopyMode2); - else - packstmt->u.expr = NULL; - break; - case ST_GOTO: - packstmt->u.statementnum = CInline_GetStatementNumber(stmt->next, scan->label->stmt); - break; - case ST_IFGOTO: - case ST_IFNGOTO: - packstmt->u.ifgoto.expr = CInline_CopyExpression(scan->expr, CopyMode2); - packstmt->u.ifgoto.statementnum = CInline_GetStatementNumber(stmt->next, scan->label->stmt); - break; - case ST_SWITCH: - packstmt->u.switchdata = CInline_PackSwitch(stmt->next, scan); - break; - case ST_ASM: - InlineAsm_PackAsmStatement(scan, stmt->next, &packstmt->u.asmdata.data, &packstmt->u.asmdata.size); - break; - default: - CError_FATAL(3862); - } - } -} - -void CInline_UnpackIFunctionData(Object *object, CI_FuncData *funcdata, Statement *firstStmt) { - CLabel **labels; - CI_Var *var; - ObjectList *last; - Statement *stmt; - CI_Statement *packstmt; - int i; - - cparser_fileoffset = funcdata->fileoffset; - symdecloffset = funcdata->symdecloffset; - functionbodyoffset = funcdata->functionbodyoffset; - functionbodypath = funcdata->functionbodypath; - symdeclend = funcdata->symdeclend; - - for (i = 0, var = funcdata->arguments; i < funcdata->numarguments; i++, var++) { - if (i == 0) { - last = lalloc(sizeof(ObjectList)); - arguments = last; - } else { - last->next = lalloc(sizeof(ObjectList)); - last = last->next; - } - - object = galloc(sizeof(Object)); - memclrw(object, sizeof(Object)); - last->object = object; - last->next = NULL; - - object->otype = OT_OBJECT; - object->access = ACCESSPUBLIC; - object->datatype = DLOCAL; - object->name = var->name; - object->type = var->type; - object->qual = var->qual; - CInline_SetObjectSFlags(object, var->sflags); - CFunc_SetupLocalVarInfo(object); - - if (funcdata->fileoffset.file) { - object->u.var.info->deftoken.tokenfile = funcdata->fileoffset.file; - object->u.var.info->deftoken.tokenoffset = funcdata->functionbodyoffset; - } - } - - for (i = 0, var = funcdata->locals; i < funcdata->numlocals; i++, var++) { - if (i == 0) { - last = lalloc(sizeof(ObjectList)); - locals = last; - } else { - last->next = lalloc(sizeof(ObjectList)); - last = last->next; - } - - object = galloc(sizeof(Object)); - memclrw(object, sizeof(Object)); - last->object = object; - last->next = NULL; - - object->otype = OT_OBJECT; - object->access = ACCESSPUBLIC; - object->datatype = DLOCAL; - object->name = var->name; - object->type = var->type; - object->qual = var->qual; - CInline_SetObjectSFlags(object, var->sflags); - CFunc_SetupLocalVarInfo(object); - - if (funcdata->fileoffset.file) { - object->u.var.info->deftoken.tokenfile = funcdata->fileoffset.file; - object->u.var.info->deftoken.tokenoffset = funcdata->functionbodyoffset; - } - } - - enode_idtrans = NULL; - cinline_label_trans = NULL; - - labels = lalloc(sizeof(CLabel *) * funcdata->numstatements); - memclrw(labels, sizeof(CLabel *) * funcdata->numstatements); - - for (i = 0, stmt = firstStmt, packstmt = funcdata->statements; i < funcdata->numstatements; i++, packstmt++) { - stmt->next = lalloc(sizeof(Statement)); - stmt = stmt->next; - - stmt->type = packstmt->type; - stmt->flags = packstmt->flags; - stmt->value = packstmt->value; - stmt->sourceoffset = packstmt->sourceoffset; - stmt->sourcefilepath = packstmt->sourcefilepath; - stmt->dobjstack = CInline_UnpackActions(packstmt, 0); - stmt->next = NULL; - - switch (stmt->type) { - case ST_NOP: - case ST_GOTO: - case ST_ASM: - break; - case ST_EXPRESSION: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - stmt->expr = CInline_CopyExpression(packstmt->u.expr, CopyMode3); - break; - case ST_RETURN: - if (packstmt->u.expr) - stmt->expr = CInline_CopyExpression(packstmt->u.expr, CopyMode3); - else - stmt->expr = NULL; - break; - case ST_LABEL: - labels[i] = stmt->label = newlabel(); - stmt->label->stmt = stmt; - break; - case ST_IFGOTO: - case ST_IFNGOTO: - stmt->expr = CInline_CopyExpression(packstmt->u.ifgoto.expr, CopyMode3); - break; - case ST_SWITCH: - stmt->expr = CInline_CopyExpression(packstmt->u.switchdata->expr, CopyMode3); - break; - default: - CError_FATAL(4017); - } - } - - for (stmt = firstStmt->next, packstmt = funcdata->statements; stmt; stmt = stmt->next, packstmt++) { - switch (stmt->type) { - case ST_GOTO: - CError_ASSERT(4024, stmt->label = labels[packstmt->u.statementnum]); - break; - case ST_IFGOTO: - case ST_IFNGOTO: - CError_ASSERT(4029, stmt->label = labels[packstmt->u.ifgoto.statementnum]); - break; - case ST_SWITCH: - CInline_UnpackSwitch(stmt, packstmt, labels); - break; - case ST_ASM: - InlineAsm_UnpackAsmStatement(stmt, labels, 0, packstmt->u.asmdata.data, packstmt->u.asmdata.size); - break; - } - } - - cinline_first_stmt = firstStmt->next; - - while (cinline_label_trans) { - CError_ASSERT(4045, *cinline_label_trans->labelptr = labels[cinline_label_trans->id]); - cinline_label_trans = cinline_label_trans->next; - } -} - -static void CInline_GenIFunctionCode(Object *object, CI_FuncData *func, UInt8 unk) { - Boolean saveDebugInfo; - CScopeSave saveScope; - Statement firstStmt; - - if (cparamblkptr->precompile != 1 && func) { - ObjGen_SetupSym(); - CScope_SetFunctionScope(object, &saveScope); - CFunc_FuncGenSetup(&firstStmt, object); - CInline_UnpackIFunctionData(object, func, &firstStmt); - - saveDebugInfo = copts.filesyminfo; - if (copts.nosyminline || (!symdecloffset && !symdeclend)) - copts.filesyminfo = 0; - - expanding_function = object; - recursive_inline = 0; - CInline_Expand(&firstStmt); - - if (!anyerrors) { - if (copts.filesyminfo) - CPrep_SetSourceFile(&cparser_fileoffset); - CodeGen_Generator(&firstStmt, object, unk, 0); - } - - CScope_RestoreScope(&saveScope); - copts.filesyminfo = saveDebugInfo; - } -} - -void CInline_AddDefaultFunctionAction(Object *object) { - CI_Action *action; - - for (action = cinline_actionlist; action; action = action->next) { - if (action->obj == object) - return; - } - - action = galloc(sizeof(CI_Action)); - memclrw(action, sizeof(CI_Action)); - - action->actiontype = CI_ActionDefaultFunc; - action->obj = object; - - action->next = cinline_actionlist; - cinline_actionlist = action; -} - -void CInline_AddInlineFunctionAction(Object *object, TypeClass *tclass, FileOffsetInfo *fileoffset, TokenStream *stream, Boolean flag) { - CI_Action *action; - - for (action = flag ? cinline_tactionlist : cinline_actionlist; action; action = action->next) { - if (action->obj == object) - return; - } - - CError_ASSERT(4132, IS_TYPE_FUNC(object->type)); - - TYPE_FUNC(object->type)->flags |= FUNC_IS_TEMPL_INSTANCE; - - action = galloc(sizeof(CI_Action)); - memclrw(action, sizeof(CI_Action)); - - action->actiontype = CI_ActionInlineFunc; - action->obj = object; - action->u.inlinefunc.tclass = tclass; - action->u.inlinefunc.fileoffset = *fileoffset; - action->u.inlinefunc.stream = *stream; - - if (flag) { - action->next = cinline_tactionlist; - cinline_tactionlist = action; - TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000; - } else { - action->next = cinline_actionlist; - cinline_actionlist = action; - } -} - -void CInline_AddMemberFunctionAction(Object *object, TemplClass *templ, TemplClassInst *inst, TemplateMember *tmemb) { - CI_Action *action; - - for (action = cinline_tactionlist; action; action = action->next) { - if (action->obj == object) - return; - } - - action = galloc(sizeof(CI_Action)); - memclrw(action, sizeof(CI_Action)); - - action->actiontype = CI_ActionMemberFunc; - action->obj = object; - action->u.memberfunc.templ = templ; - action->u.memberfunc.inst = inst; - action->u.memberfunc.tmemb = tmemb; - - action->next = cinline_tactionlist; - cinline_tactionlist = action; - - TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000; -} - -void CInline_AddTemplateFunctionAction(Object *object, TemplateFunction *func, TemplFuncInstance *inst) { - CI_Action *action; - - for (action = cinline_tactionlist; action; action = action->next) { - if (action->obj == object) - return; - } - - action = galloc(sizeof(CI_Action)); - memclrw(action, sizeof(CI_Action)); - - action->actiontype = CI_ActionTemplateFunc; - action->obj = object; - action->u.templatefunc.func = func; - action->u.templatefunc.inst = inst; - - action->next = cinline_tactionlist; - cinline_tactionlist = action; - - TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000; -} - -static void CInline_AddFRefList_Object(Object *object) { - ObjectList *list; - - if ( - !(object->datatype == DFUNC || object->datatype == DVFUNC) || - (object->flags & OBJECT_DEFINED) || - IS_TEMPL_FUNC(object->type) - ) - return; - - for (list = cinline_freflist; list; list = list->next) { - if (list->object == object) - return; - } - - list = lalloc(sizeof(ObjectList)); - list->object = object; - list->next = cinline_freflist; - cinline_freflist = list; - - if ((object->qual & Q_INLINE) && object->u.func.u.ifuncdata) - CInline_AddFRefList_InlineFunc(object->u.func.u.ifuncdata); -} - -static void CInline_AddFRefList_ExAction(ExceptionAction *exc) { - while (exc) { - switch (exc->type) { - case EAT_DESTROYLOCAL: - CInline_AddFRefList_Object(exc->data.destroy_local.dtor); - break; - case EAT_DESTROYLOCALCOND: - CInline_AddFRefList_Object(exc->data.destroy_local_cond.dtor); - break; - case EAT_DESTROYLOCALOFFSET: - CInline_AddFRefList_Object(exc->data.destroy_local_offset.dtor); - break; - case EAT_DESTROYLOCALPOINTER: - CInline_AddFRefList_Object(exc->data.destroy_local_pointer.dtor); - break; - case EAT_DESTROYLOCALARRAY: - CInline_AddFRefList_Object(exc->data.destroy_local_array.dtor); - break; - case EAT_DESTROYPARTIALARRAY: - CInline_AddFRefList_Object(exc->data.destroy_partial_array.dtor); - break; - case EAT_DESTROYMEMBER: - case EAT_DESTROYBASE: - CInline_AddFRefList_Object(exc->data.destroy_member.dtor); - break; - case EAT_DESTROYMEMBERCOND: - CInline_AddFRefList_Object(exc->data.destroy_member_cond.dtor); - break; - case EAT_DESTROYMEMBERARRAY: - CInline_AddFRefList_Object(exc->data.destroy_member_array.dtor); - break; - case EAT_DELETEPOINTER: - case EAT_DELETELOCALPOINTER: - CInline_AddFRefList_Object(exc->data.delete_pointer.deletefunc); - break; - case EAT_DELETEPOINTERCOND: - CInline_AddFRefList_Object(exc->data.delete_pointer_cond.deletefunc); - break; - case EAT_CATCHBLOCK: - case EAT_ACTIVECATCHBLOCK: - case EAT_SPECIFICATION: - case EAT_TERMINATE: - break; - default: - CError_FATAL(4307); - } - exc = exc->prev; - } -} - -static void CInline_AddFRefList_ExprCB(ENode *expr) { - CInline_AddFRefList_Object(expr->data.objref); -} - -static void CInline_AddFRefList_Expr(ENode *expr) { - CExpr_SearchExprTree(expr, CInline_AddFRefList_ExprCB, 1, EOBJREF); -} - -static void CInline_AddFRefList_Statement(Statement *stmt) { - while (stmt) { - if (stmt->dobjstack) - CInline_AddFRefList_ExAction(stmt->dobjstack); - - switch (stmt->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_ASM: - break; - case ST_RETURN: - if (!stmt->expr) - break; - case ST_EXPRESSION: - case ST_SWITCH: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_GOTOEXPR: - CInline_AddFRefList_Expr(stmt->expr); - break; - default: - CError_FATAL(4368); - } - - stmt = stmt->next; - } -} - -static void CInline_AddFRefList_InlineFunc(CI_FuncData *data) { - short i; - CI_Statement *stmt; - ExceptionAction *exc; - - for (i = 0; i < data->numstatements; i++) { - stmt = data->statements + i; - - switch (stmt->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - case ST_ASM: - break; - case ST_EXPRESSION: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - CInline_AddFRefList_Expr(stmt->u.expr); - break; - case ST_RETURN: - if (stmt->u.expr) - CInline_AddFRefList_Expr(stmt->u.expr); - break; - case ST_IFGOTO: - case ST_IFNGOTO: - CInline_AddFRefList_Expr(stmt->u.ifgoto.expr); - break; - case ST_SWITCH: - CInline_AddFRefList_Expr(stmt->u.switchdata->expr); - break; - default: - CError_FATAL(4420); - } - - for (exc = data->statements[i].dobjstack; exc; exc = exc->prev) { - switch (exc->type) { - case EAT_DESTROYLOCAL: - CInline_AddFRefList_Object(exc->data.destroy_local.dtor); - break; - case EAT_DESTROYLOCALCOND: - CInline_AddFRefList_Object(exc->data.destroy_local_cond.dtor); - break; - case EAT_DESTROYLOCALOFFSET: - CInline_AddFRefList_Object(exc->data.destroy_local_offset.dtor); - break; - case EAT_DESTROYLOCALPOINTER: - CInline_AddFRefList_Object(exc->data.destroy_local_pointer.dtor); - break; - case EAT_DESTROYLOCALARRAY: - CInline_AddFRefList_Object(exc->data.destroy_local_array.dtor); - break; - case EAT_DESTROYPARTIALARRAY: - break; - case EAT_DESTROYMEMBER: - case EAT_DESTROYBASE: - CInline_AddFRefList_Object(exc->data.destroy_member.dtor); - break; - case EAT_DESTROYMEMBERCOND: - CInline_AddFRefList_Object(exc->data.destroy_member_cond.dtor); - break; - case EAT_DESTROYMEMBERARRAY: - CInline_AddFRefList_Object(exc->data.destroy_member_array.dtor); - break; - case EAT_DELETEPOINTER: - case EAT_DELETELOCALPOINTER: - CInline_AddFRefList_Object(exc->data.delete_pointer.deletefunc); - break; - case EAT_DELETEPOINTERCOND: - CInline_AddFRefList_Object(exc->data.delete_pointer_cond.deletefunc); - break; - case EAT_CATCHBLOCK: - case EAT_ACTIVECATCHBLOCK: - case EAT_SPECIFICATION: - case EAT_TERMINATE: - break; - default: - CError_FATAL(4470); - } - } - } -} - -static void CInline_GenerateTemplateInline(Object *object) { - CI_Action **ptr; - CI_Action *action; - - ptr = &cinline_tactionlist; - while ((action = *ptr)) { - if (object == action->obj) { - *ptr = action->next; - action->next = cinline_actionlist; - cinline_actionlist = action; - - TYPE_FUNC(object->type)->flags &= ~FUNC_FLAGS_200000; - return; - } - - ptr = &action->next; - } - - CError_FATAL(4499); -} - -void CInline_ObjectAddrRef(Object *object) { - CI_FuncData *funcdata; - - object->flags |= OBJECT_FLAGS_2; - - switch (object->datatype) { - case DFUNC: - case DVFUNC: - if ( - (object->qual & Q_INLINE) && - (funcdata = object->u.func.u.ifuncdata) && - !(object->flags & OBJECT_DEFINED) && - !(TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) - ) - { - CI_Export *export = galloc(sizeof(CI_Export)); - - export->object = object; - export->funcdata = funcdata; - export->xC = 0; - - export->next = cinline_exportlist; - cinline_exportlist = export; - - object->flags |= OBJECT_DEFINED; - return; - } - else if ( - (TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED) && - !(TYPE_FUNC(object->type)->flags & FUNC_DEFINED) - ) - { - CInline_AddDefaultFunctionAction(object); - return; - } - else if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_200000) - { - CInline_GenerateTemplateInline(object); - return; - } - return; - - case DALIAS: - CInline_ObjectAddrRef(object->u.alias.object); - return; - - case DDATA: - if (object->qual & Q_INLINE_DATA) - CInit_ExportConst(object); - - if (object->flags & OBJECT_LAZY) { - object->flags &= ~OBJECT_LAZY; - CParser_CallBackAction(object); - } - return; - } -} - -static Boolean CInline_CheckDependencies(ObjectList *list) { - Object *object; - Boolean result; - - result = 0; - - while (list) { - object = list->object; - - if ( - (TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED) && - !(TYPE_FUNC(object->type)->flags & FUNC_DEFINED) - ) - { - CInline_AddDefaultFunctionAction(object); - result = 1; - } - else if ( - (object->qual & Q_IS_TEMPLATED) && - CTempl_InlineFunctionCheck(object) - ) - { - result = 1; - } - else { - CI_Action *action; - for (action = cinline_actionlist; action; action = action->next) { - if (object == action->obj) { - result = 1; - break; - } - } - - if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_200000) { - CInline_GenerateTemplateInline(object); - result = 1; - } - } - - list = list->next; - } - - return result; -} - -static Boolean CInline_IsSmallFunction(Object *object, Statement *stmt) { - SInt32 statementCount; - ObjectList *list; - SInt32 localSize; - - statementCount = 0; - while (stmt) { - if (stmt->type != ST_NOP && stmt->type != ST_LABEL) - statementCount++; - if (statementCount > 15) - return 0; - stmt = stmt->next; - } - - for (list = locals, localSize = 0; list; list = list->next) - localSize += list->object->type->size; - - if (localSize > 1024) - return 0; - - return 1; -} - -static Boolean CInline_NoFPLocals(void) { - ObjectList *list; - - for (list = locals; list; list = list->next) { - if (IS_TYPE_FLOAT(list->object->type)) - return 0; - } - - return 1; -} - -void CInline_GenFunc(Statement *stmt, Object *object, UInt8 unk) { - CI_FuncData *funcdata; - CI_Export *export; - Boolean flag24; - Boolean flag30; - - TYPE_FUNC(object->type)->flags |= OBJECT_FLAGS_2; - - flag24 = 0; - flag30 = 0; - if (!(object->qual & Q_INLINE)) { - if ( - copts.auto_inline && - !copts.dontinline && - CInline_CanInline(object, stmt->next) && - CInline_IsSmallFunction(object, stmt->next) - ) - { - flag24 = 1; - flag30 = 1; - TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_800; - } - } else { - flag30 = 1; - } - - if (flag30) { - COpt_SimpleOptimizer(object, stmt); - - funcdata = galloc(sizeof(CI_FuncData)); - CInline_PackIFunctionData(funcdata, stmt, object); - - object->u.func.u.ifuncdata = funcdata; - - if (!flag24 && !(object->flags & OBJECT_FLAGS_2)) { - if (cinline_gendeps) { - cinline_freflist = NULL; - CInline_AddFRefList_Statement(stmt); - CInline_CheckDependencies(cinline_freflist); - } - return; - } - } - - object->flags |= OBJECT_DEFINED; - - cinline_freflist = NULL; - CInline_AddFRefList_Statement(stmt); - - if (CInline_CheckDependencies(cinline_freflist) || copts.defer_codegen) { - if (!flag30) { - funcdata = galloc(sizeof(CI_FuncData)); - CInline_PackIFunctionData(funcdata, stmt, object); - } else { - funcdata = object->u.func.u.ifuncdata; - } - - export = galloc(sizeof(CI_Export)); - export->object = object; - export->funcdata = funcdata; - export->xC = unk; - - export->next = cinline_exportlist; - cinline_exportlist = export; - - return; - } - - expanding_function = object; - recursive_inline = 0; - CInline_Expand(stmt); - - if (copts.filesyminfo) - CPrep_SetSourceFile(&cparser_fileoffset); - - if (!anyerrors) - CodeGen_Generator(stmt, object, unk, 0); -} - -static void CInline_GenerateDefaultFunc(Object *object) { - TypeClass *tclass; - - CError_ASSERT(4770, TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED); - CError_ASSERT(4771, TYPE_FUNC(object->type)->flags & FUNC_METHOD); - - tclass = TYPE_METHOD(object->type)->theclass; - - if (object == CClass_DefaultConstructor(tclass)) { - if (object->u.func.defargdata) - CABI_MakeDefaultArgConstructor(tclass, object); - else - CABI_MakeDefaultConstructor(tclass, object); - } else if (object == CClass_CopyConstructor(tclass)) { - CABI_MakeDefaultCopyConstructor(tclass, object); - } else if (object == CClass_AssignmentOperator(tclass)) { - CABI_MakeDefaultAssignmentOperator(tclass, object); - } else if (object == CClass_Destructor(tclass)) { - CABI_MakeDefaultDestructor(tclass, object); - } else { - CError_FATAL(4805); - } -} - -static TemplClassInst *CInline_FindNestedTemplInst(TypeClass *tclass) { - NameSpace *nspace; - - while (tclass) { - if ((tclass->flags & CLASS_IS_TEMPL_INST)) - return TEMPL_CLASS_INST(tclass); - - if (!copts.template_patch) - break; - - nspace = tclass->nspace->parent; - tclass = NULL; - while (nspace) { - if (nspace->theclass) { - tclass = nspace->theclass; - break; - } - nspace = nspace->parent; - } - } - - return NULL; -} - -static void CInline_GenerateInlineFunc(CI_Action *action) { - Object *object; - TemplClassInst *inst; - DeclInfo di; - SInt32 streamState; - - object = action->obj; - - CPrep_StreamInsert(&action->u.inlinefunc.stream, &streamState); - cparser_fileoffset = action->u.inlinefunc.fileoffset; - symdecloffset = cparser_fileoffset.tokenline; - - switch ((tk = lex())) { - case ':': - case '{': - case TK_TRY: - break; - default: - CError_FATAL(4860); - } - - symdecltoken = *CPrep_CurStreamElement(); - - TYPE_FUNC(object->type)->flags &= ~FUNC_DEFINED; - if (IS_TYPE_METHOD(object->type) && (inst = CInline_FindNestedTemplInst(TYPE_METHOD(object->type)->theclass))) { - CTempl_ParseInstanceScopeFunction(object, inst, NULL); - } else { - memclrw(&di, sizeof(di)); - if (action->u.inlinefunc.tclass) { - if ((inst = CInline_FindNestedTemplInst(action->u.inlinefunc.tclass))) { - CTempl_ParseInstanceScopeFunction(object, inst, action->u.inlinefunc.tclass); - } else { - CFunc_ParseFuncDef(object, &di, action->u.inlinefunc.tclass, 0, 0, NULL); - } - } else { - CFunc_ParseFuncDef(object, &di, NULL, 0, 0, NULL); - } - } - - CPrep_StreamRemove(&action->u.inlinefunc.stream, &streamState); -} - -Boolean CInline_CanFreeLHeap(void) { - CI_Action *action; - - if (!anyerrors) { - for (action = cinline_actionlist; action; action = action->next) { - if (action->actiontype == CI_ActionInlineFunc) - return 0; - } - } - - return 1; -} - -Boolean CInline_GenerateDeferredFuncs(void) { - CI_Action *action; - CI_Export *export; - - if (!anyerrors) { - if ((action = cinline_actionlist)) { - cinline_actionlist = action->next; - cinline_gendeps = 1; - - switch (action->actiontype) { - case CI_ActionDefaultFunc: - CInline_GenerateDefaultFunc(action->obj); - break; - case CI_ActionInlineFunc: - if (!(action->obj->flags & OBJECT_DEFINED)) - CInline_GenerateInlineFunc(action); - break; - case CI_ActionMemberFunc: - if (!(TYPE_FUNC(action->obj->type)->flags & FUNC_DEFINED)) - CTempl_InstantiateMember( - action->u.memberfunc.templ, action->u.memberfunc.inst, - action->u.memberfunc.tmemb, action->obj, 0); - break; - case CI_ActionTemplateFunc: - if (!(TYPE_FUNC(action->obj->type)->flags & FUNC_DEFINED) && !action->u.templatefunc.inst->is_specialized) - CTempl_GenFuncInstance(action->u.templatefunc.func, action->u.templatefunc.inst, 0); - break; - default: - CError_FATAL(5001); - } - - cinline_gendeps = 0; - return 1; - } else { - if ((export = cinline_exportlist) && !copts.defer_codegen) { - cinline_exportlist = export->next; - CInline_GenIFunctionCode(export->object, export->funcdata, export->xC); - return 1; - } - } - } - - return 0; -} - -static InitExpr *CInline_InitTemplateData(InitExpr *init) { - Statement *stmt; - CLabel *label; - Object *object; - Object *data; - - object = init->object; - - data = CParser_NewCompilerDefDataObject(); - data->type = TYPE(&stsignedchar); - data->name = CParser_NameConcat("__init__", CMangler_GetLinkName(object)->name); - data->qual = Q_WEAK; - CInit_DeclareData(data, NULL, NULL, data->type->size); - - stmt = CFunc_AppendStatement(ST_IFGOTO); - stmt->expr = create_objectnode(data); - label = newlabel(); - stmt->label = label; - - do { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = CInline_CopyExpression(init->expr, CopyMode0); - init = init->next; - } while (init && init->object == object); - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = makediadicnode(create_objectnode(data), intconstnode(TYPE(&stsignedchar), 1), EASS); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - return init; -} - -void CInline_Finish(void) { - NameSpace *nspace; - Boolean saveDebugInfo; - Statement firstStmt; - Statement *stmt; - InitExpr *init; - Boolean doMore; - - if (!init_expressions || anyerrors) - return; - - cinline_freflist = NULL; - - for (init = init_expressions; init; init = init->next) - CInline_AddFRefList_Expr(init->expr); - - CInline_CheckDependencies(cinline_freflist); - - do { - doMore = CInline_GenerateDeferredFuncs(); - } while (doMore); - - nspace = CFunc_FuncGenSetup(&firstStmt, NULL); - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - init = init_expressions; - while (init) { - if (init->object->nspace->theclass && (init->object->nspace->theclass->flags & CLASS_IS_TEMPL_INST)) { - init = CInline_InitTemplateData(init); - } else { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = CInline_CopyExpression(init->expr, CopyMode0); - init = init->next; - } - } - - CFunc_CodeCleanup(&firstStmt); - - expanding_function = NULL; - recursive_inline = 0; - CInline_Expand(&firstStmt); - - if (!anyerrors) { - if (copts.filesyminfo) - CPrep_SetSourceFile(&cparser_fileoffset); - CodeGen_Generator(&firstStmt, NULL, 0, 1); - } - - cscope_current = nspace->parent; - copts.filesyminfo = saveDebugInfo; -} |