summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CInline.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CInline.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/CInline.c')
-rw-r--r--compiler_and_linker/unsorted/CInline.c4206
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 = &copy->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;
-}