summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CException.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/CException.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/CException.c')
-rw-r--r--compiler_and_linker/unsorted/CException.c2183
1 files changed, 0 insertions, 2183 deletions
diff --git a/compiler_and_linker/unsorted/CException.c b/compiler_and_linker/unsorted/CException.c
deleted file mode 100644
index d68ce13..0000000
--- a/compiler_and_linker/unsorted/CException.c
+++ /dev/null
@@ -1,2183 +0,0 @@
-#include "compiler/CException.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInline.h"
-#include "compiler/CInit.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-typedef struct UniqueObj {
- struct UniqueObj *next;
- Object *object;
- SInt32 uniqueid;
-} UniqueObj;
-
-ExceptionAction *cexcept_dobjstack;
-Boolean cexcept_hasdobjects;
-Boolean cexcept_magic;
-static UniqueObj *cexcept_uniqueobjs;
-static Boolean cexcept_canthrow;
-static DtorTemp *cexcept_dtortemps;
-static Statement *cexcept_prevstmt;
-static ExceptionAction *cexcept_eabefore;
-static ExceptionAction *cexcept_eaafter;
-static Boolean cexcept_expandtrycatch;
-static Boolean cexcept_hastrycatch;
-static Boolean cexcept_serialize;
-
-// forward decls
-static ENode *CExcept_TempTransExprCond(ENode *expr);
-static ENode *CExcept_TempTransExpr(ENode *expr);
-
-void CExcept_Setup(void) {
- cexcept_dobjstack = NULL;
- cexcept_uniqueobjs = NULL;
- cexcept_hasdobjects = 0;
- cexcept_magic = 0;
-}
-
-Boolean CExcept_CanThrowException(Object *object, Boolean flag) {
- if (copts.optEH && IS_TYPE_FUNC(object->type)) {
- if (flag)
- return 1;
-
- if (TYPE_FUNC(object->type)->flags & FUNC_NOTHROW)
- return 0;
-
- if (
- !flag &&
- TYPE_FUNC(object->type)->exspecs &&
- TYPE_FUNC(object->type)->exspecs &&
- !TYPE_FUNC(object->type)->exspecs->type
- )
- return 0;
-
- if (
- copts.optEH2 &&
- !(object->qual & Q_MANGLE_NAME) &&
- object != rt_ptmf_call &&
- object != rt_ptmf_scall &&
- object != Rdync_func &&
- object != rt_som_glue1 &&
- object != rt_som_glue2 &&
- object != rt_som_glue3 &&
- object != carr_func &&
- object != cnar_func &&
- object != darr_func &&
- object != dnar_func &&
- object != dnar3_func &&
- object != Xthrw_func
- )
- return 0;
- }
-
- return 1;
-}
-
-void CExcept_CheckStackRefs(ExceptionAction *actions) {
- while (actions) {
- switch (actions->type) {
- case EAT_DESTROYLOCAL:
- CInline_ObjectAddrRef(actions->data.destroy_local.dtor);
- break;
- case EAT_DESTROYLOCALCOND:
- CInline_ObjectAddrRef(actions->data.destroy_local_cond.dtor);
- break;
- case EAT_DESTROYLOCALOFFSET:
- CInline_ObjectAddrRef(actions->data.destroy_local_offset.dtor);
- break;
- case EAT_DESTROYLOCALPOINTER:
- CInline_ObjectAddrRef(actions->data.destroy_local_pointer.dtor);
- break;
- case EAT_DESTROYLOCALARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_local_array.dtor);
- break;
- case EAT_DESTROYPARTIALARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_partial_array.dtor);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- CInline_ObjectAddrRef(actions->data.destroy_member.dtor);
- break;
- case EAT_DESTROYMEMBERCOND:
- CInline_ObjectAddrRef(actions->data.destroy_member_cond.dtor);
- break;
- case EAT_DESTROYMEMBERARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_member_array.dtor);
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- CInline_ObjectAddrRef(actions->data.delete_pointer.deletefunc);
- break;
- case EAT_DELETEPOINTERCOND:
- CInline_ObjectAddrRef(actions->data.delete_pointer_cond.deletefunc);
- break;
- case EAT_CATCHBLOCK:
- case EAT_ACTIVECATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(192);
- }
- actions = actions->prev;
- }
-}
-
-void CExcept_CompareSpecifications(ExceptSpecList *a, ExceptSpecList *b) {
- ExceptSpecList *aa;
- ExceptSpecList *bb;
-
- aa = a;
- bb = b;
- while (1) {
- if (!aa) {
- if (!bb)
- break;
- CError_Error(CErrorStr265);
- return;
- }
-
- if (!bb) {
- CError_Error(CErrorStr265);
- return;
- }
-
- aa = aa->next;
- bb = bb->next;
- }
-
- if (a->type == NULL) {
- if (b->type != NULL)
- CError_Error(CErrorStr265);
- } else if (b->type == NULL) {
- CError_Error(CErrorStr265);
- } else {
- for (aa = a; aa; aa = aa->next) {
- for (bb = b; bb; bb = bb->next) {
- if (is_typesame(aa->type, bb->type) && aa->qual == bb->qual)
- break;
- }
-
- if (bb == NULL) {
- CError_Error(CErrorStr265);
- return;
- }
- }
- }
-}
-
-Boolean CExcept_ActionCompare(ExceptionAction *a, ExceptionAction *b) {
- if (a->type == b->type) {
- switch (a->type) {
- case EAT_DESTROYLOCAL:
- return a->data.destroy_local.local == b->data.destroy_local.local;
- case EAT_DESTROYLOCALCOND:
- return a->data.destroy_local_cond.local == b->data.destroy_local_cond.local;
- case EAT_DESTROYLOCALOFFSET:
- return a->data.destroy_local_offset.local == b->data.destroy_local_offset.local &&
- a->data.destroy_local_offset.offset == b->data.destroy_local_offset.offset;
- case EAT_DESTROYLOCALPOINTER:
- return a->data.destroy_local_pointer.pointer == b->data.destroy_local_pointer.pointer;
- case EAT_DESTROYLOCALARRAY:
- return a->data.destroy_local_array.localarray == b->data.destroy_local_array.localarray;
- case EAT_DESTROYPARTIALARRAY:
- return a->data.destroy_partial_array.arraypointer == b->data.destroy_partial_array.arraypointer;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- return a->data.destroy_member.objectptr == b->data.destroy_member.objectptr &&
- a->data.destroy_member.offset == b->data.destroy_member.offset;
- case EAT_DESTROYMEMBERCOND:
- return a->data.destroy_member_cond.objectptr == b->data.destroy_member_cond.objectptr &&
- a->data.destroy_member_cond.offset == b->data.destroy_member_cond.offset;
- case EAT_DESTROYMEMBERARRAY:
- return a->data.destroy_member_array.objectptr == b->data.destroy_member_array.objectptr &&
- a->data.destroy_member_array.offset == b->data.destroy_member_array.offset;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- return a->data.delete_pointer.pointerobject == b->data.delete_pointer.pointerobject &&
- a->data.delete_pointer.deletefunc == b->data.delete_pointer.deletefunc;
- case EAT_DELETEPOINTERCOND:
- return a->data.delete_pointer_cond.cond == b->data.delete_pointer_cond.cond;
- case EAT_CATCHBLOCK:
- return a->data.catch_block.catch_label == b->data.catch_block.catch_label;
- case EAT_ACTIVECATCHBLOCK:
- return a->data.active_catch_block.catch_info_object == b->data.active_catch_block.catch_info_object;
- case EAT_TERMINATE:
- return 1;
- case EAT_SPECIFICATION:
- return a->data.specification.unexp_id == b->data.specification.unexp_id;
- default:
- CError_FATAL(314);
- }
- }
-
- return 0;
-}
-
-int CExcept_IsSubList(ExceptionAction *a, ExceptionAction *b) {
- int diff;
- int i;
- int count1;
- int count2;
- ExceptionAction *scan;
-
- if (a == b)
- return 0;
-
- count1 = 0;
- scan = a;
- while (scan) {
- scan = scan->prev;
- count1++;
- }
-
- scan = b;
- count2 = 0;
- while (scan) {
- scan = scan->prev;
- count2++;
- }
-
- diff = count2 - count1;
- if (diff < 0)
- return -1;
-
- for (i = 0; i < diff; i++)
- b = b->prev;
-
- while (a != b) {
- if (!a || !b || !CExcept_ActionCompare(a, b))
- return -1;
- a = a->prev;
- b = b->prev;
- }
-
- return diff;
-}
-
-Boolean CExcept_ActionNeedsDestruction(ExceptionAction *action) {
- switch (action->type) {
- case EAT_CATCHBLOCK:
- return 0;
- case EAT_DESTROYLOCAL:
- case EAT_DESTROYLOCALOFFSET:
- case EAT_DESTROYLOCALARRAY:
- case EAT_DELETELOCALPOINTER:
- case EAT_ACTIVECATCHBLOCK:
- return 1;
- case EAT_NOP:
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_DESTROYBASE:
- break;
- default:
- CError_FATAL(363);
- }
-
- return 0;
-}
-
-ENode *CExcept_RegisterDestructorObject(Object *local, SInt32 offset, Object *dtor, Boolean flag) {
- ExceptionAction *action;
- ENode *expr;
- Object *dtorObject;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- expr = create_objectrefnode(local);
- dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1);
-
- if (offset == 0) {
- action->type = EAT_DESTROYLOCAL;
- action->data.destroy_local.local = local;
- action->data.destroy_local.dtor = dtorObject;
- } else {
- action->type = EAT_DESTROYLOCALOFFSET;
- action->data.destroy_local_offset.local = local;
- action->data.destroy_local_offset.dtor = dtorObject;
- action->data.destroy_local_offset.offset = offset;
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- }
-
- cexcept_hasdobjects = 1;
- return expr;
-}
-
-void CExcept_RegisterLocalArray(Statement *stmt, Object *localarray, Object *dtor, SInt32 elements, SInt32 element_size) {
- ExceptionAction *action;
- Object *dtorObject;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1);
-
- action->type = EAT_DESTROYLOCALARRAY;
- action->data.destroy_local_array.localarray = localarray;
- action->data.destroy_local_array.dtor = dtorObject;
- action->data.destroy_local_array.elements = elements;
- action->data.destroy_local_array.element_size = element_size;
-
- cexcept_hasdobjects = 1;
-}
-
-void CExcept_RegisterDeleteObject(Statement *stmt, Object *pointerobject, Object *deletefunc) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- action->type = EAT_DELETELOCALPOINTER;
- action->data.delete_pointer.pointerobject = pointerobject;
- action->data.delete_pointer.deletefunc = deletefunc;
-
- cexcept_hasdobjects = 1;
-}
-
-static void CExcept_PatchConstructorAction(Statement *stmt, ExceptionAction *actionArg) {
- ExceptionAction *action30;
- ExceptionAction *action;
- ExceptionAction *scan;
-
- for (action = stmt->dobjstack; action; action = action->prev) {
- switch (action->type) {
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_SPECIFICATION:
- case EAT_DESTROYBASE:
- goto exitFirstLoop;
- case EAT_CATCHBLOCK:
- action30 = action;
- while (1) {
- if (!action30->prev)
- goto exitFirstLoop;
- action30 = action30->prev;
- if (action30->type != EAT_CATCHBLOCK) {
- CError_FATAL(481);
- }
- }
- }
- }
- exitFirstLoop:
- if (action == NULL) {
- while (stmt) {
- if ((scan = stmt->dobjstack)) {
- while (1) {
- if (scan == actionArg)
- break;
- if (scan->prev == NULL) {
- scan->prev = actionArg;
- break;
- }
- scan = scan->prev;
- }
- } else {
- stmt->dobjstack = actionArg;
- }
- stmt = stmt->next;
- }
- } else {
- actionArg->prev = action;
- while (stmt) {
- if (stmt->dobjstack != action) {
- scan = stmt->dobjstack;
- do {
- if (scan == actionArg)
- goto nextStmt;
- if (scan->prev == action) {
- scan->prev = actionArg;
- goto nextStmt;
- }
- } while ((scan = scan->prev));
-
- while (1) {
- if (action->type == EAT_CATCHBLOCK && action->prev == NULL)
- return;
-
- action = action->prev;
- if (!action)
- CError_FATAL(531);
- }
- } else {
- stmt->dobjstack = actionArg;
- }
- nextStmt:
- stmt = stmt->next;
- }
- }
-}
-
-void CExcept_Terminate(void) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_TERMINATE;
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-}
-
-void CExcept_Magic(void) {
- cexcept_magic = 1;
-}
-
-static Object *CExcept_FindLocalObject(char *name) {
- NameResult result;
- NameSpaceObjectList *list;
-
- list = CScope_FindObjectList(&result, GetHashNameNodeExport(name));
- if (list && list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DLOCAL)
- return OBJECT(list->object);
-
- CError_FATAL(580);
- return NULL;
-}
-
-void CExcept_ArrayInit(void) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_DESTROYPARTIALARRAY;
- action->data.destroy_partial_array.arraypointer = CExcept_FindLocalObject("ptr");
- action->data.destroy_partial_array.arraycounter = CExcept_FindLocalObject("i");
- action->data.destroy_partial_array.dtor = CExcept_FindLocalObject("dtor");
- action->data.destroy_partial_array.element_size = CExcept_FindLocalObject("size");
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-}
-
-void CExcept_RegisterMember(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, Object *cond, Boolean isMember) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- if (cond == NULL) {
- if (isMember) {
- action->type = EAT_DESTROYMEMBER;
- action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- } else {
- action->type = EAT_DESTROYBASE;
- action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy0);
- }
- action->data.destroy_member.objectptr = objectptr;
- action->data.destroy_member.offset = offset;
- } else {
- CError_ASSERT(632, cond->type == TYPE(&stsignedshort));
- action->type = EAT_DESTROYMEMBERCOND;
- action->data.destroy_member_cond.objectptr = objectptr;
- action->data.destroy_member_cond.cond = cond;
- action->data.destroy_member_cond.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- action->data.destroy_member_cond.offset = offset;
- }
-
- CExcept_PatchConstructorAction(stmt, action);
- stmt->flags |= StmtFlag_2;
-}
-
-void CExcept_RegisterMemberArray(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, SInt32 elements, SInt32 element_size) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_DESTROYMEMBERARRAY;
- action->data.destroy_member_array.objectptr = objectptr;
- action->data.destroy_member_array.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- action->data.destroy_member_array.offset = offset;
- action->data.destroy_member_array.elements = elements;
- action->data.destroy_member_array.element_size = element_size;
-
- CExcept_PatchConstructorAction(stmt, action);
- stmt->flags |= StmtFlag_2;
-}
-
-static Statement *CExcept_DestroyLocal(ExceptionAction *ea, Statement *stmt, Object *object, Object *dtor, SInt32 offset) {
- ENode *expr;
-
- expr = create_objectrefnode(object);
- if (offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
-
- expr = CABI_DestroyObject(dtor, expr, CABIDestroy1, 1, 0);
-
- CError_ASSERT(687, expr->type == EFUNCCALL && expr->data.funccall.funcref->type == EOBJREF);
- if (expr->data.funccall.funcref->data.objref->datatype == DVFUNC)
- expr->data.funccall.funcref->flags |= ENODE_FLAG_80;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- stmt->dobjstack = ea->prev;
- return stmt;
-}
-
-static Statement *CExcept_DestroyLocalPointer(ExceptionAction *ea, Statement *stmt, Object *object, Object *deletefunc) {
- Statement *newStmt;
-
- newStmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- newStmt->expr = funccallexpr(deletefunc, create_objectnode2(object), NULL, NULL, NULL);
- newStmt->dobjstack = ea->prev;
- return newStmt;
-}
-
-static Statement *CExcept_DestroyLocalArray(ExceptionAction *ea, Statement *stmt, Object *object, Object *dtor, SInt32 elements, SInt32 element_size) {
- Statement *newStmt;
- ENode *dtorExpr;
-
- newStmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
-
- if (dtor)
- dtorExpr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- else
- dtorExpr = nullnode();
-
- newStmt->expr = funccallexpr(
- darr_func,
- create_objectrefnode(object),
- dtorExpr,
- intconstnode(TYPE(&stunsignedlong), element_size),
- intconstnode(TYPE(&stunsignedlong), elements)
- );
-
- newStmt->dobjstack = ea->prev;
- return newStmt;
-}
-
-static Statement *CExcept_EndCatch(ExceptionAction *ea, Statement *stmt) {
- stmt = CFunc_InsertStatement(ST_ENDCATCHDTOR, stmt);
- stmt->expr = create_objectrefnode(ea->data.active_catch_block.catch_info_object);
- stmt->dobjstack = ea->prev;
- if (!ea->data.active_catch_block.call_dtor)
- stmt->type = ST_ENDCATCH;
- return stmt;
-}
-
-Statement *CExcept_ActionCleanup(ExceptionAction *ea, Statement *stmt) {
- switch (ea->type) {
- case EAT_DESTROYLOCALCOND:
- case EAT_DESTROYLOCALPOINTER:
- case EAT_DESTROYPARTIALARRAY:
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_DELETEPOINTER:
- case EAT_DELETEPOINTERCOND:
- case EAT_CATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- case EAT_DESTROYBASE:
- break;
- case EAT_DESTROYLOCAL:
- stmt = CExcept_DestroyLocal(
- ea, stmt,
- ea->data.destroy_local.local,
- ea->data.destroy_local.dtor,
- 0);
- break;
- case EAT_DESTROYLOCALOFFSET:
- stmt = CExcept_DestroyLocal(
- ea, stmt,
- ea->data.destroy_local.local,
- ea->data.destroy_local.dtor,
- ea->data.destroy_local_offset.offset);
- break;
- case EAT_DELETELOCALPOINTER:
- stmt = CExcept_DestroyLocalPointer(
- ea, stmt,
- ea->data.delete_pointer.pointerobject,
- ea->data.delete_pointer.deletefunc);
- break;
- case EAT_DESTROYLOCALARRAY:
- stmt = CExcept_DestroyLocalArray(
- ea, stmt,
- ea->data.destroy_local_array.localarray,
- ea->data.destroy_local_array.dtor,
- ea->data.destroy_local_array.elements,
- ea->data.destroy_local_array.element_size);
- break;
- case EAT_ACTIVECATCHBLOCK:
- stmt = CExcept_EndCatch(ea, stmt);
- break;
- default:
- CError_FATAL(827);
- }
-
- return stmt;
-}
-
-static void CExcept_MangleNameSpaceName(NameSpace *nspace) {
- while (nspace) {
- if (nspace->name) {
- CExcept_MangleNameSpaceName(nspace->parent);
- AppendGListName(&name_mangle_list, nspace->name->name);
- AppendGListName(&name_mangle_list, "::");
- break;
- }
- nspace = nspace->parent;
- }
-}
-
-static void CExcept_MangleClassName(TypeClass *tclass) {
- NameSpace *nspace;
- char buf[64];
-
- CExcept_MangleNameSpaceName(tclass->nspace->parent);
- AppendGListName(&name_mangle_list, tclass->classname->name);
-
- for (nspace = tclass->nspace->parent; nspace; nspace = nspace->parent) {
- if (!nspace->is_global && !nspace->is_templ && !nspace->name) {
- CError_ASSERT(868, cscope_currentfunc != NULL);
-
- sprintf(buf, "*%" PRIxPTR "*%" PRIxPTR "*", &cscope_currentfunc, &nspace);
- AppendGListName(&name_mangle_list, buf);
- break;
- }
- }
-}
-
-typedef struct BCL {
- struct BCL *next;
- TypeClass *tclass;
- SInt32 offset;
- Boolean is_virtual;
- Boolean is_public;
- Boolean is_ambig;
-} BCL;
-
-static void CExcept_MakeBaseClassListAmbig(BCL *bcl, TypeClass *tclass) {
- BCL *scan;
- ClassList *list;
-
- for (scan = bcl; scan; scan = scan->next) {
- if (scan->tclass == tclass)
- scan->is_ambig = 1;
- }
-
- for (list = tclass->bases; list; list = list->next)
- CExcept_MakeBaseClassListAmbig(bcl, list->base);
-}
-
-static BCL *CExcept_GetBaseClassList(BCL *bcl, TypeClass *tclass1, TypeClass *tclass2, SInt32 offset, Boolean is_virtual, Boolean is_public) {
- BCL *node;
- ClassList *base;
- Boolean new_is_public;
-
- for (node = bcl; node; node = node->next) {
- if (node->tclass == tclass2) {
- if (is_virtual && node->is_virtual) {
- if (is_public)
- node->is_public = 1;
- } else {
- CExcept_MakeBaseClassListAmbig(bcl, tclass2);
- }
- return bcl;
- }
- }
-
- node = lalloc(sizeof(BCL));
- node->tclass = tclass2;
- node->offset = offset;
- node->is_virtual = is_virtual;
- node->is_public = is_public;
- node->is_ambig = 0;
- node->next = bcl;
- bcl = node;
-
- for (base = tclass2->bases; base; base = base->next) {
- new_is_public = is_public && (base->access == ACCESSPUBLIC);
- bcl = base->is_virtual
- ? CExcept_GetBaseClassList(bcl, tclass1, base->base, CClass_VirtualBaseOffset(tclass1, base->base), 1, new_is_public)
- : CExcept_GetBaseClassList(bcl, tclass1, base->base, offset + base->offset, 0, new_is_public);
- }
-
- return bcl;
-}
-
-static void CExcept_MangleClass(TypeClass *tclass) {
- BCL *bcl;
- char buf[20];
-
- for (bcl = CExcept_GetBaseClassList(NULL, tclass, tclass, 0, 0, 1); bcl; bcl = bcl->next) {
- if (bcl->is_public && !bcl->is_ambig) {
- CExcept_MangleClassName(bcl->tclass);
- AppendGListByte(&name_mangle_list, '!');
-
- if (bcl->offset) {
- sprintf(buf, "%" PRId32 "!", bcl->offset);
- AppendGListName(&name_mangle_list, buf);
- } else {
- AppendGListByte(&name_mangle_list, '!');
- }
- }
- }
-}
-
-static ENode *CExcept_GetTypeID(Type *type, UInt32 qual, Boolean flag) {
- ENode *expr;
- TypePointer my_tptr;
-
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) || (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_CLASS(TPTR_TARGET(type)))) {
- name_mangle_list.size = 0;
- if (IS_TYPE_POINTER_ONLY(type)) {
- AppendGListByte(&name_mangle_list, '*');
- type = TPTR_TARGET(type);
- } else {
- AppendGListByte(&name_mangle_list, '!');
- }
-
- if (flag) {
- CExcept_MangleClass(TYPE_CLASS(type));
- } else {
- CExcept_MangleClassName(TYPE_CLASS(type));
- AppendGListByte(&name_mangle_list, '!');
- }
- } else {
- if (IS_TYPE_POINTER_ONLY(type)) {
- if (TPTR_QUAL(type) & (Q_CONST | Q_VOLATILE)) {
- my_tptr = *TYPE_POINTER(type);
- my_tptr.qual = 0;
- type = TYPE(&my_tptr);
- }
- } else {
- qual = 0;
- }
- CMangler_MangleType(type, qual);
- }
-
- AppendGListByte(&name_mangle_list, 0);
-
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewPointerType(TYPE(&stchar));
- expr->data.string.size = name_mangle_list.size;
- expr->data.string.data = galloc(name_mangle_list.size);
- memcpy(expr->data.string.data, *name_mangle_list.data, name_mangle_list.size);
- return expr;
-}
-
-static Object *CExcept_TypeID(Type *type, UInt32 qual) {
- ENode *expr = CExcept_GetTypeID(type, qual, 0);
- CError_ASSERT(1086, expr->type == ESTRINGCONST);
- return CInit_DeclareString(expr->data.string.data, expr->data.string.size, 0, 0);
-}
-
-void CExcept_ScanExceptionSpecification(TypeFunc *tfunc) {
- ExceptSpecList *exspecs;
- ExceptSpecList *exspec;
- DeclInfo di;
-
- exspecs = NULL;
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return;
- }
-
- if ((tk = lex()) != ')') {
- while (1) {
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass)
- CError_Error(CErrorStr177);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr146);
-
- if (IS_TYPE_POINTER_ONLY(di.thetype)) {
- if (TPTR_QUAL(di.thetype) & (Q_CONST | Q_VOLATILE)) {
- TypePointer *newtype = galloc(sizeof(TypePointer));
- *newtype = *TYPE_POINTER(di.thetype);
- newtype->qual = 0;
- di.thetype = TYPE(newtype);
- }
- } else {
- di.qual = 0;
- }
-
- for (exspec = exspecs; exspec; exspec = exspec->next) {
- if (is_typesame(exspec->type, di.thetype) && exspec->qual == di.qual)
- break;
- }
-
- if (!exspec) {
- exspec = galloc(sizeof(ExceptSpecList));
- memclrw(exspec, sizeof(ExceptSpecList));
- exspec->next = exspecs;
- exspec->type = di.thetype;
- exspec->qual = di.qual;
- exspecs = exspec;
- }
-
- if (tk == ')')
- break;
-
- if (tk != ',') {
- CError_Error(CErrorStr115);
- break;
- }
-
- tk = lex();
- }
- }
-
- if (!exspecs) {
- exspecs = galloc(sizeof(ExceptSpecList));
- memclrw(exspecs, sizeof(ExceptSpecList));
- }
- tfunc->exspecs = exspecs;
- tk = lex();
-}
-
-static ENode *CExcept_CallCopyCtor(Object *object, Type *type, ENode *expr1, ENode *expr2) {
- ENodeList *list;
- ENode *expr;
- FuncArg *arg;
-
- if (
- !IS_TYPE_FUNC(object->type) ||
- !(arg = TYPE_FUNC(object->type)->args) ||
- !(arg = arg->next)
- )
- CError_FATAL(1169);
-
- expr = funccallexpr(object, expr1, NULL, NULL, NULL);
- list = expr->data.funccall.args;
-
- if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(1179, arg = arg->next);
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = intconstnode(TYPE(&stsignedshort), 1);
- }
-
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = expr2;
-
- while ((arg = arg->next)) {
- CError_ASSERT(1195, arg->dexpr);
-
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = CExpr_GetDefaultArgument(expr->data.funccall.funcref, arg);
- }
-
- return expr;
-}
-
-ENode *CExcept_ScanThrowExpression(void) {
- ENode *expr;
- Object *func;
- ENode *resultExpr;
- Object *obj;
- ENode *thrownExpr;
- ENode *tempExpr;
-
- if (!copts.exceptions)
- CError_Error(CErrorStr252);
-
- switch ((tk = lex())) {
- case ')':
- case ',':
- case ':':
- case ';':
- expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
- break;
- default:
- thrownExpr = pointer_generation(assignment_expression());
- obj = create_temp_object(thrownExpr->rtype);
- if (!IS_TYPE_CLASS(thrownExpr->rtype) || !(resultExpr = CExpr_IsTempConstruction(thrownExpr, thrownExpr->rtype, &expr))) {
- tempExpr = create_objectrefnode(obj);
- if (IS_TYPE_CLASS(thrownExpr->rtype) && (func = CClass_CopyConstructor(TYPE_CLASS(thrownExpr->rtype)))) {
- resultExpr = CExcept_CallCopyCtor(func, thrownExpr->rtype, tempExpr, getnodeaddress(thrownExpr, 0));
- } else {
- if (thrownExpr->rtype->size == 0)
- CError_Error(CErrorStr146);
-
- tempExpr = makemonadicnode(tempExpr, EINDIRECT);
- tempExpr->rtype = thrownExpr->rtype;
- resultExpr = makediadicnode(tempExpr, thrownExpr, EASS);
- resultExpr = makediadicnode(resultExpr, create_objectrefnode(obj), ECOMMA);
- resultExpr->rtype = TYPE(&void_ptr);
- }
- } else {
- *expr = *create_objectrefnode(obj);
- }
-
- expr = CExcept_GetTypeID(thrownExpr->rtype, ENODE_QUALS(thrownExpr), 1);
- if (IS_TYPE_CLASS(thrownExpr->rtype) && (func = CClass_Destructor(TYPE_CLASS(thrownExpr->rtype)))) {
- expr = funccallexpr(
- Xthrw_func,
- expr,
- resultExpr,
- create_objectrefnode(CABI_GetDestructorObject(func, CABIDestroy1)),
- NULL);
- } else {
- expr = funccallexpr(
- Xthrw_func,
- expr,
- resultExpr,
- nullnode(),
- NULL);
- }
- }
-
- expr->flags |= ENODE_FLAG_VOLATILE;
- return expr;
-}
-
-static Boolean CExcept_MightNeedDtor(Type *type) {
- if (type) {
- if (IS_TYPE_CLASS(type)) {
- if (!CClass_Destructor(TYPE_CLASS(type)))
- return 0;
- } else if (IS_TYPE_POINTER_ONLY(type)) {
- if (!(TPTR_QUAL(type) & Q_REFERENCE) || !IS_TYPE_CLASS(TPTR_TARGET(type)))
- return 0;
- } else {
- return 0;
- }
- }
-
- return 1;
-}
-
-typedef struct CatchBlock {
- struct CatchBlock *next;
- Object *catch_object;
- Object *catch_info_object;
- Statement *stmt;
- Statement *anotherStmt;
- Type *type;
- UInt32 qual;
-} CatchBlock;
-
-static void CExcept_PatchDObjStack(Statement *beginCatchStmt, Statement *tryEndStmt, Statement *endStmt, CatchBlock *catchBlock) {
- ExceptionAction *ea;
- ExceptionAction *stackHead;
- ExceptionAction *stackTail;
- ExceptionAction *firstEA;
- Statement *stmt;
- Object *catch_info_object;
- Boolean call_dtor;
-
- catch_info_object = catchBlock->catch_info_object;
- call_dtor = 0;
- stackHead = stackTail = beginCatchStmt->dobjstack;
- firstEA = NULL;
-
- while (catchBlock) {
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
-
- ea->prev = stackTail;
- stackTail = ea;
-
- if (!firstEA)
- firstEA = ea;
-
- ea->type = EAT_CATCHBLOCK;
- ea->data.catch_block.catch_object = catchBlock->catch_object;
- ea->data.catch_block.catch_label = catchBlock->stmt->label;
- if (catchBlock->type)
- ea->data.catch_block.catch_typeid = CExcept_TypeID(catchBlock->type, catchBlock->qual);
- ea->data.catch_block.catch_info_object = catch_info_object;
-
- if (!call_dtor && CExcept_MightNeedDtor(catchBlock->type))
- call_dtor = 1;
-
- ea->data.catch_block.catch_type = catchBlock->type;
- ea->data.catch_block.catch_qual = catchBlock->qual;
- catchBlock = catchBlock->next;
- }
-
- stmt = beginCatchStmt;
- while (1) {
- if ((ea = stmt->dobjstack) != stackHead) {
- while (1) {
- CError_ASSERT(1404, ea);
- if (ea->prev == stackTail)
- break;
- if (ea->prev == stackHead) {
- ea->prev = stackTail;
- break;
- }
- ea = ea->prev;
- }
- } else {
- stmt->dobjstack = stackTail;
- }
-
- if (stmt == endStmt)
- break;
-
- if (stmt == tryEndStmt) {
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->prev = stackHead;
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->data.active_catch_block.call_dtor = call_dtor;
- stackTail = ea;
- }
-
- stmt = stmt->next;
- CError_ASSERT(1426, stmt);
- }
-
- cexcept_hasdobjects = 1;
-}
-
-static void CExcept_CheckTryObjects(ENode *expr) {
- if (expr->data.objref->datatype == DLOCAL && expr->data.objref->u.var.info)
- expr->data.objref->u.var.info->noregister = 1;
-}
-
-static ENode *CExcept_CatchExpressionInit(DeclInfo *di, CatchBlock *catchBlock) {
- Object *catch_object;
- Object *copyCtor;
- Object *dtor;
- ENode *expr;
-
- if (CScope_FindName(cscope_current, di->name))
- CError_Error(CErrorStr122, di->name->name);
-
- catch_object = CParser_NewLocalDataObject(di, 1);
- CFunc_SetupLocalVarInfo(catch_object);
- CScope_AddObject(cscope_current, di->name, OBJ_BASE(catch_object));
- catchBlock->catch_object = catch_object;
-
- expr = makediadicnode(
- create_objectrefnode(catchBlock->catch_info_object),
- intconstnode(TYPE(&stunsignedlong), 12),
- EADD);
- expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(di->thetype));
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = CDecl_NewPointerType(di->thetype);
-
- if (IS_TYPE_REFERENCE(di->thetype))
- return makediadicnode(create_objectnode2(catch_object), expr, EASS);
-
- if (IS_TYPE_CLASS(di->thetype) && (copyCtor = CClass_CopyConstructor(TYPE_CLASS(di->thetype)))) {
- dtor = CClass_Destructor(TYPE_CLASS(di->thetype));
- return CExcept_CallCopyCtor(
- copyCtor,
- di->thetype,
- (dtor == NULL) ? create_objectrefnode(catch_object) : CExcept_RegisterDestructorObject(catch_object, 0, dtor, 0),
- expr);
- }
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = di->thetype;
- return makediadicnode(create_objectnode(catch_object), expr, EASS);
-}
-
-void CExcept_ScanTryBlock(DeclThing *dt, Boolean flag) {
- Object *catch_info_object; // r27
- Statement *beginCatchStmt; // r14
- Statement *tryEndStmt; // r16
- Statement *endStmt; // r17
- Statement *stmt; // r14
- CLabel *catchEndLabel; // r19
- CLabel *endLabel; // r24
- CatchBlock *catchStack; // r23
- CatchBlock *catchBlock; // r22
- DeclBlock *declBlock; // r20
- DeclInfo di;
-
- if (!copts.exceptions)
- CError_Error(CErrorStr252);
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
- if (cexcept_magic) {
- catch_info_object->name = GetHashNameNodeExport("__exception_magic");
- CScope_AddObject(cscope_current, catch_info_object->name, OBJ_BASE(catch_info_object));
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->flags = StmtFlag_1;
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
-
- beginCatchStmt = CFunc_AppendStatement(ST_BEGINCATCH);
- beginCatchStmt->expr = create_objectrefnode(catch_info_object);
-
- if (tk != '{') {
- CError_Error(CErrorStr135);
- return;
- }
-
- CFunc_CompoundStatement(dt);
-
- if (tk != TK_CATCH) {
- CError_Error(CErrorStr242);
- return;
- }
-
- stmt = CFunc_AppendStatement(ST_GOTO);
- catchEndLabel = stmt->label = newlabel();
- tryEndStmt = stmt;
-
- endLabel = newlabel();
- catchStack = NULL;
-
- while (1) {
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->flags = StmtFlag_1;
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
-
- declBlock = NULL;
-
- catchBlock = lalloc(sizeof(ExceptionAction));
- memclrw(catchBlock, sizeof(ExceptionAction));
- catchBlock->next = catchStack;
- catchStack = catchBlock;
-
- catchBlock->stmt = stmt;
- catchBlock->catch_info_object = catch_info_object;
-
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- break;
- }
-
- if ((tk = lex()) == TK_ELLIPSIS) {
- tk = lex();
- } else {
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (di.x48)
- CError_Error(CErrorStr121);
- if (di.storageclass)
- CError_Error(CErrorStr177);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
-
- if (IS_TYPE_FUNC(di.thetype))
- di.thetype = CDecl_NewPointerType(di.thetype);
- else if (IS_TYPE_ARRAY(di.thetype))
- di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype));
-
- IsCompleteType(di.thetype);
- if (IS_TYPE_CLASS(di.thetype) && (TYPE_CLASS(di.thetype)->flags & CLASS_ABSTRACT))
- CError_AbstractClassError(TYPE_CLASS(di.thetype));
-
- catchBlock->type = di.thetype;
- catchBlock->qual = di.qual;
-
- if (di.name) {
- ENode *expr;
- declBlock = CFunc_NewDeclBlock();
- expr = CExcept_CatchExpressionInit(&di, catchBlock);
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
- }
- }
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- break;
- }
-
- if ((tk = lex()) != '{') {
- CError_Error(CErrorStr123);
- break;
- }
-
- CFunc_CompoundStatement(dt);
- if (flag) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
- }
-
- catchBlock->anotherStmt = stmt;
-
- if (declBlock)
- CFunc_RestoreBlock(declBlock);
-
- if (tk != TK_CATCH)
- break;
-
- CFunc_AppendStatement(ST_GOTO)->label = endLabel;
- }
-
- endStmt = CFunc_AppendStatement(ST_LABEL);
- endStmt->label = endLabel;
- endLabel->stmt = endStmt;
-
- CExcept_PatchDObjStack(beginCatchStmt, tryEndStmt, endStmt, catchBlock);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = catchEndLabel;
- catchEndLabel->stmt = stmt;
-}
-
-static Statement *CExcept_InsertPrevStatement(StatementType sttype) {
- Statement *stmt = CFunc_InsertStatement(sttype, cexcept_prevstmt);
- stmt->sourceoffset = stmt->next->sourceoffset;
- stmt->sourcefilepath = stmt->next->sourcefilepath;
- stmt->dobjstack = cexcept_eabefore;
- return stmt;
-}
-
-static Object *CExcept_GetETEMPObject(ENode *expr) {
- UniqueObj *uobj;
- SInt32 id;
-
- if ((id = expr->data.temp.uniqueid)) {
- for (uobj = cexcept_uniqueobjs; uobj; uobj = uobj->next) {
- if (uobj->uniqueid == id)
- return uobj->object;
- }
-
- uobj = galloc(sizeof(UniqueObj));
- uobj->next = cexcept_uniqueobjs;
- cexcept_uniqueobjs = uobj;
- uobj->uniqueid = id;
- return (uobj->object = create_temp_object(expr->data.temp.type));
- } else {
- return create_temp_object(expr->data.temp.type);
- }
-}
-
-static ENode *CExcept_TempTrans_ETEMP(ENode *expr) {
- Object *object;
- ExceptionAction *ea;
- DtorTemp *dtorTemp;
- Object *dtor;
-
- object = CExcept_GetETEMPObject(expr);
- if (expr->data.temp.needs_dtor) {
- dtorTemp = lalloc(sizeof(DtorTemp));
- dtorTemp->next = cexcept_dtortemps;
- cexcept_dtortemps = dtorTemp;
- dtorTemp->object = object;
- dtorTemp->temp = NULL;
-
- if (
- !IS_TYPE_CLASS(expr->data.temp.type) ||
- !(dtorTemp->dtor = CClass_Destructor(TYPE_CLASS(expr->data.temp.type)))
- )
- CError_FATAL(1749);
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
- ea->type = EAT_DESTROYLOCAL;
- ea->data.destroy_local.local = dtorTemp->object;
- ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
- }
-
- expr->type = EOBJREF;
- expr->data.objref = object;
- return expr;
-}
-
-static ENode *CExcept_TransNewException(ENode *expr, Boolean isCond) {
- Object *tempObj;
- CLabel *label;
- Boolean isArray;
- Statement *stmt;
- ExceptionAction *ea;
- ENode *result;
-
- isArray = expr->type == ENEWEXCEPTIONARRAY;
-
- if (isCond) {
- expr->data.newexception.initexpr = CExcept_TempTransExprCond(expr->data.newexception.initexpr);
- expr->data.newexception.tryexpr = CExcept_TempTransExprCond(expr->data.newexception.tryexpr);
- tempObj = create_temp_object(TYPE(&stchar));
-
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS);
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DELETEPOINTERCOND;
- ea->data.delete_pointer_cond.pointerobject = expr->data.newexception.pointertemp;
- ea->data.delete_pointer_cond.deletefunc = expr->data.newexception.deletefunc;
- ea->data.delete_pointer_cond.cond = tempObj;
-
- if (isArray) {
- result = makediadicnode(
- makediadicnode(
- expr->data.newexception.initexpr,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 1), EASS),
- ECOMMA
- ),
- expr->data.newexception.tryexpr,
- ECOMMA
- );
-
- result = makediadicnode(
- result,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS),
- ECOMMA
- );
-
- result = makediadicnode(
- result,
- create_objectnode(expr->data.newexception.pointertemp),
- ECOMMA
- );
- } else {
- result = makediadicnode(
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 1), EASS),
- expr->data.newexception.tryexpr,
- ECOMMA
- );
-
- result = makediadicnode(
- expr->data.newexception.initexpr,
- makediadicnode(
- result,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS),
- ECOMMA
- ),
- ELAND
- );
-
- result = makediadicnode(
- result,
- create_objectnode(expr->data.newexception.pointertemp),
- ECOMMA
- );
- }
- } else {
- expr->data.newexception.initexpr = CExcept_TempTransExpr(expr->data.newexception.initexpr);
- expr->data.newexception.tryexpr = CExcept_TempTransExpr(expr->data.newexception.tryexpr);
-
- if (isArray) {
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = expr->data.newexception.initexpr;
- } else {
- stmt = CExcept_InsertPrevStatement(ST_IFNGOTO);
- stmt->expr = expr->data.newexception.initexpr;
- label = newlabel();
- stmt->label = label;
- }
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.newexception.tryexpr;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- ea->type = EAT_DELETEPOINTER;
- ea->data.delete_pointer.pointerobject = expr->data.newexception.pointertemp;
- ea->data.delete_pointer.deletefunc = expr->data.newexception.deletefunc;
- stmt->dobjstack = ea;
-
- if (!isArray) {
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label;
- label->stmt = stmt;
- stmt->dobjstack = cexcept_eabefore;
- }
-
- cexcept_prevstmt = stmt;
- result = create_objectnode(expr->data.newexception.pointertemp);
- }
-
- result->rtype = expr->rtype;
- return result;
-}
-
-static ENode *CExcept_TransInitTryCatch(ENode *expr, Boolean isCond) {
- CLabel *label1;
- CLabel *label2;
- CLabel *label3;
- Object *catch_info_object;
- Statement *stmt;
- ExceptionAction *ea;
-
- cexcept_hastrycatch = 1;
-
- if (isCond) {
- CError_ASSERT(1877, !cexcept_expandtrycatch);
-
- cexcept_serialize = 1;
- expr->data.itc.initexpr = CExcept_TempTransExprCond(expr->data.itc.initexpr);
- expr->data.itc.tryexpr = CExcept_TempTransExprCond(expr->data.itc.tryexpr);
- expr->data.itc.catchexpr = CExcept_TempTransExprCond(expr->data.itc.catchexpr);
- expr->data.itc.result = CExcept_TempTransExprCond(expr->data.itc.result);
- return expr;
- }
-
- expr->data.itc.initexpr = CExcept_TempTransExpr(expr->data.itc.initexpr);
- expr->data.itc.tryexpr = CExcept_TempTransExpr(expr->data.itc.tryexpr);
- expr->data.itc.catchexpr = CExcept_TempTransExpr(expr->data.itc.catchexpr);
- expr->data.itc.result = CExcept_TempTransExpr(expr->data.itc.result);
-
- if (!cexcept_expandtrycatch)
- return expr;
-
- label1 = newlabel();
- label2 = newlabel();
- label3 = newlabel();
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
-
- stmt = CExcept_InsertPrevStatement(ST_IFNGOTO);
- stmt->expr = expr->data.itc.initexpr;
- stmt->label = label3;
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_CATCHBLOCK;
- ea->data.catch_block.catch_label = label2;
- ea->data.catch_block.catch_info_object = catch_info_object;
- ea->prev = stmt->dobjstack;
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->flags = StmtFlag_1;
- stmt->label = label1;
- label1->stmt = stmt;
- stmt->dobjstack = ea;
-
- stmt = CFunc_InsertStatement(ST_BEGINCATCH, stmt);
- stmt->expr = create_objectrefnode(catch_info_object);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.itc.tryexpr;
-
- stmt = CFunc_InsertStatement(ST_GOTO, stmt);
- stmt->label = label3;
-
- CError_ASSERT(1928, stmt->dobjstack == ea);
-
- stmt->dobjstack = ea->prev;
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->prev = stmt->dobjstack;
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->flags = StmtFlag_1;
- stmt->label = label2;
- label2->stmt = stmt;
- stmt->dobjstack = ea;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.itc.catchexpr;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label3;
- label3->stmt = stmt;
-
- CError_ASSERT(1968, stmt->dobjstack == ea);
-
- stmt->dobjstack = ea->prev;
-
- cexcept_prevstmt = stmt;
- return expr->data.itc.result;
-}
-
-static ENode *CExcept_TempTransFuncCall(ENode *expr, Boolean isCond) {
- ENodeList *tempArg;
- ENodeList **argArray;
- ENodeList *args;
- ExceptionAction *ea;
- Statement *stmt;
- DtorTemp *dtorTemp;
- ENode *tempNode;
-
- tempArg = NULL;
- if ((args = expr->data.funccall.args)) {
- tempNode = args->node;
- if (tempNode->type == ETEMP) {
- if (tempNode->data.temp.needs_dtor)
- tempArg = args;
- } else if (args->next) {
- tempNode = args->next->node;
- if (tempNode->type == ETEMP) {
- if (tempNode->data.temp.needs_dtor)
- tempArg = args->next;
- }
- }
- }
-
- if (tempArg) {
- if (isCond) {
- ENodeList *arg = args;
- SInt32 i = 0;
- while (arg) {
- arg = arg->next;
- i++;
- }
-
- argArray = lalloc(sizeof(ENodeList *) * i);
- for (args = expr->data.funccall.args, i = 0; args; args = args->next)
- argArray[i++] = args;
-
- while (i > 0) {
- i--;
- if (argArray[i] != tempArg)
- argArray[i]->node = CExcept_TempTransExprCond(argArray[i]->node);
- }
- } else {
- while (args) {
- if (args != tempArg)
- args->node = CExcept_TempTransExpr(args->node);
- args = args->next;
- }
- }
-
- dtorTemp = lalloc(sizeof(DtorTemp));
- dtorTemp->next = cexcept_dtortemps;
- cexcept_dtortemps = dtorTemp;
-
- dtorTemp->object = CExcept_GetETEMPObject(tempNode);
- dtorTemp->temp = NULL;
-
- if (
- !IS_TYPE_CLASS(tempNode->data.temp.type) ||
- !(dtorTemp->dtor = CClass_Destructor(TYPE_CLASS(tempNode->data.temp.type)))
- )
- CError_FATAL(2046);
-
- tempNode->type = EOBJREF;
- tempNode->data.objref = dtorTemp->object;
-
- if (isCond) {
- Type *type24 = expr->rtype;
- dtorTemp->temp = create_temp_object(TYPE(&stchar));
-
- expr = makediadicnode(
- expr,
- makediadicnode(create_objectnode(dtorTemp->temp), intconstnode(TYPE(&stchar), 1), EASS),
- ECOMMA
- );
-
- expr = makediadicnode(
- expr,
- create_objectrefnode(dtorTemp->object),
- ECOMMA
- );
- expr->rtype = type24;
-
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(
- create_objectnode(dtorTemp->temp),
- intconstnode(TYPE(&stchar), 0),
- EASS
- );
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DESTROYLOCALCOND;
- ea->data.destroy_local_cond.local = dtorTemp->object;
- ea->data.destroy_local_cond.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
- ea->data.destroy_local_cond.cond = dtorTemp->temp;
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
- } else {
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = expr;
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DESTROYLOCAL;
- ea->data.destroy_local.local = dtorTemp->object;
- ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
-
- expr = lalloc(sizeof(ENode));
- *expr = *stmt->expr;
- expr->type = EOBJREF;
- expr->data.objref = tempArg->node->data.objref;
- }
- return expr;
- } else {
- if (isCond) {
- SInt32 i = 0;
- while (args) {
- args = args->next;
- i++;
- }
-
- argArray = lalloc(sizeof(ENodeList *) * i);
- for (args = expr->data.funccall.args, i = 0; args; args = args->next)
- argArray[i++] = args;
-
- while (i > 0) {
- i--;
- argArray[i]->node = CExcept_TempTransExprCond(argArray[i]->node);
- }
-
- expr->data.funccall.funcref = CExcept_TempTransExprCond(expr->data.funccall.funcref);
- } else {
- while (args) {
- args->node = CExcept_TempTransExpr(args->node);
- args = args->next;
- }
-
- expr->data.funccall.funcref = CExcept_TempTransExpr(expr->data.funccall.funcref);
- }
-
- return expr;
- }
-}
-
-static ENode *CExcept_TempTransExprCond(ENode *expr) {
- switch (expr->type) {
- case ETEMP:
- return CExcept_TempTrans_ETEMP(expr);
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- return CExcept_TransNewException(expr, 1);
- case EINITTRYCATCH:
- return CExcept_TransInitTryCatch(expr, 1);
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CExcept_TempTransExprCond(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CExcept_TempTransExprCond(expr->data.nullcheck.condexpr);
- return expr;
- case ECOND:
- expr->data.cond.cond = CExcept_TempTransExprCond(expr->data.cond.cond);
- expr->data.cond.expr1 = CExcept_TempTransExprCond(expr->data.cond.expr1);
- expr->data.cond.expr2 = CExcept_TempTransExprCond(expr->data.cond.expr2);
- return expr;
- case ELAND:
- case ELOR:
- expr->data.diadic.left = CExcept_TempTransExprCond(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- return expr;
- case EFUNCCALL:
- case EFUNCCALLP:
- return CExcept_TempTransFuncCall(expr, 1);
- 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 ECOMMA:
- case EROTL:
- case EROTR:
- expr->data.diadic.left = CExcept_TempTransExprCond(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- 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 = CExcept_TempTransExprCond(expr->data.monadic);
- return expr;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ELABEL:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
- default:
- CError_FATAL(2236);
- return expr;
- }
-}
-
-static ENode *CExcept_TempTransExpr(ENode *expr) {
- switch (expr->type) {
- case ETEMP:
- return CExcept_TempTrans_ETEMP(expr);
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- return CExcept_TransNewException(expr, 0);
- case EINITTRYCATCH:
- return CExcept_TransInitTryCatch(expr, 0);
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CExcept_TempTransExpr(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CExcept_TempTransExprCond(expr->data.nullcheck.condexpr);
- return expr;
- case ECOND:
- expr->data.cond.cond = CExcept_TempTransExpr(expr->data.cond.cond);
- expr->data.cond.expr1 = CExcept_TempTransExprCond(expr->data.cond.expr1);
- expr->data.cond.expr2 = CExcept_TempTransExprCond(expr->data.cond.expr2);
- return expr;
- case ELAND:
- case ELOR:
- case ECOMMA:
- expr->data.diadic.left = CExcept_TempTransExpr(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- return expr;
- case EFUNCCALL:
- case EFUNCCALLP:
- return CExcept_TempTransFuncCall(expr, 0);
- 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 EROTL:
- case EROTR:
- expr->data.diadic.left = CExcept_TempTransExpr(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExpr(expr->data.diadic.right);
- 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 = CExcept_TempTransExpr(expr->data.monadic);
- return expr;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EMFPOINTER:
- case EPRECOMP:
- case ELABEL:
- case EOBJLIST:
- case EMEMBER:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
- default:
- CError_FATAL(2350);
- return expr;
- }
-}
-
-static Statement *CExcept_DtorTransform(Statement *stmt) {
- DtorTemp *dtorTemp;
- Statement *curStmt;
- CLabel *lastLabel;
-
- dtorTemp = cexcept_dtortemps;
- curStmt = stmt;
- while (dtorTemp) {
- if (
- cexcept_eaafter &&
- (cexcept_eaafter->type == EAT_DESTROYLOCAL || cexcept_eaafter->type == EAT_DESTROYLOCALCOND) &&
- cexcept_eaafter->data.destroy_local.local == dtorTemp->object
- )
- {
- cexcept_eaafter = cexcept_eaafter->prev;
- } else {
- CError_FATAL(2374);
- }
-
- if (dtorTemp->temp) {
- curStmt = CFunc_InsertStatement(ST_IFNGOTO, curStmt);
- curStmt->expr = create_objectnode(dtorTemp->temp);
- curStmt->dobjstack = cexcept_eaafter;
- lastLabel = curStmt->label = newlabel();
- }
-
- curStmt = CFunc_InsertStatement(ST_EXPRESSION, curStmt);
- curStmt->expr = CABI_DestroyObject(dtorTemp->dtor, create_objectrefnode(dtorTemp->object), CABIDestroy1, 1, 0);
- curStmt->dobjstack = cexcept_eaafter;
-
- if (dtorTemp->temp) {
- curStmt = CFunc_InsertStatement(ST_LABEL, curStmt);
- curStmt->label = lastLabel;
- lastLabel->stmt = curStmt;
- }
-
- dtorTemp = dtorTemp->next;
- }
-
- return curStmt;
-}
-
-static void CExcept_TempTransform(Statement *stmt, Boolean flag1, Boolean flag2) {
- Statement *prevStmt;
- Statement *iter;
- Statement copy;
- Object *tempObj;
-
- prevStmt = cexcept_prevstmt;
- cexcept_dtortemps = NULL;
- cexcept_serialize = 0;
- cexcept_expandtrycatch = 0;
- cexcept_hastrycatch = 0;
- stmt->expr = CExcept_TempTransExpr(stmt->expr);
-
- if (cexcept_hastrycatch) {
- cexcept_expandtrycatch = 1;
- if (cexcept_serialize) {
- CInline_SerializeStatement(stmt);
- cexcept_prevstmt = stmt;
- } else {
- cexcept_prevstmt = prevStmt;
- }
-
- iter = prevStmt;
- while (1) {
- CError_ASSERT(2425, iter);
-
- switch (iter->type) {
- case ST_RETURN:
- CError_ASSERT(2429, iter->expr != NULL);
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- iter->expr = CExcept_TempTransExpr(iter->expr);
- }
-
- if (iter == stmt)
- break;
- cexcept_prevstmt = iter;
- iter = iter->next;
- }
- }
-
- if (cexcept_dtortemps) {
- if (!flag1) {
- if (flag2) {
- ENode *expr = stmt->expr;
- CError_ASSERT(2456, !IS_TYPE_CLASS(expr->rtype) || !CClass_Destructor(TYPE_CLASS(expr->rtype)));
-
- tempObj = create_temp_object(expr->rtype);
- stmt->expr = makediadicnode(create_objectnode(tempObj), expr, EASS);
- }
-
- copy = *stmt;
- stmt->type = ST_EXPRESSION;
- stmt = CExcept_DtorTransform(stmt);
- stmt = CFunc_InsertStatement(copy.type, stmt);
- stmt->label = copy.label;
-
- if (flag2)
- stmt->expr = create_objectnode(tempObj);
- else
- stmt->expr = nullnode();
- } else {
- CExcept_DtorTransform(stmt);
- }
- }
-}
-
-static void CExcept_CleanupExceptionActions(Statement *stmt) {
- Statement *iter;
- ENode *expr;
- ExceptionAction *ea;
-
- cexcept_prevstmt = stmt;
- for (iter = stmt; iter; iter = iter->next) {
- cexcept_eabefore = cexcept_eaafter = ea = iter->dobjstack;
-
- if (iter->flags & StmtFlag_2) {
- cexcept_eabefore = ea->prev;
- } else if (iter->type == ST_EXPRESSION) {
- expr = iter->expr;
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.left;
- if (ENODE_IS(expr, EINDIRECT))
- expr = expr->data.monadic;
-
- if (
- ENODE_IS(expr, EFUNCCALL) &&
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- CClass_IsConstructor(expr->data.funccall.funcref->data.objref) &&
- iter->dobjstack &&
- iter->dobjstack->type == EAT_DESTROYLOCAL &&
- expr->data.funccall.args &&
- ENODE_IS(expr->data.funccall.args->node, EOBJREF) &&
- expr->data.funccall.args->node->data.objref == iter->dobjstack->data.destroy_local.local
- )
- cexcept_eabefore = cexcept_eabefore->prev;
- }
-
- switch (iter->type) {
- case ST_EXPRESSION:
- CExcept_TempTransform(iter, 1, 0);
- break;
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CExcept_TempTransform(iter, 0, 1);
- break;
- case ST_RETURN:
- if (iter->expr) {
- CExcept_TempTransform(
- iter,
- 0,
- CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) != 1
- );
- }
- break;
- }
-
- iter->dobjstack = cexcept_eabefore;
- cexcept_prevstmt = iter;
- }
-}
-
-static void CExcept_InsertSpecificationActions(Statement *stmt, ExceptSpecList *exspecs) {
- Statement *iter;
- Statement *last;
- ExceptionAction *ea_spec;
- ExceptionAction *ea;
- ExceptSpecList *spec_iter;
- SInt32 i;
- Object *catch_info_object;
- CLabel *label;
-
- ea_spec = lalloc(sizeof(ExceptionAction));
- memclrw(ea_spec, sizeof(ExceptionAction));
- ea_spec->type = EAT_SPECIFICATION;
-
- for (iter = stmt; iter; iter = iter->next) {
- if ((ea = iter->dobjstack)) {
- while (1) {
- if (ea->type == EAT_SPECIFICATION)
- break;
- if (ea->prev == NULL) {
- ea->prev = ea_spec;
- break;
- }
- ea = ea->prev;
- }
- } else {
- iter->dobjstack = ea_spec;
- }
- }
-
- last = stmt;
- while (last->next)
- last = last->next;
-
- if (last->type != ST_GOTO && last->type != ST_RETURN) {
- last = CFunc_InsertStatement(ST_RETURN, last);
- last->expr = NULL;
- last->dobjstack = NULL;
- if (TYPE_FUNC(cscope_currentfunc->type)->functype != &stvoid && (copts.pedantic || copts.cplusplus))
- CError_Warning(CErrorStr184);
- }
-
- last = CFunc_InsertStatement(ST_LABEL, last);
- last->label = newlabel();
- last->label->stmt = last;
- last->flags = StmtFlag_1;
- last->dobjstack = NULL;
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
-
- if (!exspecs->type)
- exspecs = NULL;
-
- i = 0;
- spec_iter = exspecs;
- while (spec_iter) {
- spec_iter = spec_iter->next;
- i++;
- }
-
- ea_spec->data.specification.unexp_ids = i;
- ea_spec->data.specification.unexp_id = galloc(sizeof(Object *) * i);
- ea_spec->data.specification.unexp_label = last->label;
- ea_spec->data.specification.unexp_info_object = catch_info_object;
-
- i = 0;
- while (exspecs) {
- ea_spec->data.specification.unexp_id[i] = CExcept_TypeID(exspecs->type, exspecs->qual);
- exspecs = exspecs->next;
- i++;
- }
-
- last = CFunc_InsertStatement(ST_EXPRESSION, last);
- last->expr = funccallexpr(Xunex_func, create_objectrefnode(catch_info_object), NULL, NULL, NULL);
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->data.active_catch_block.call_dtor = 1;
- last->dobjstack = ea;
-
- last = CFunc_InsertStatement(ST_LABEL, last);
- last->label = label = newlabel();
- last->label->stmt = last;
- last->dobjstack = NULL;
-
- last = CFunc_InsertStatement(ST_GOTO, last);
- last->label = label;
-}
-
-static void CExcept_HasFuncCallCallBack(ENode *expr) {
- ENode *funcref = expr->data.funccall.funcref;
- if (ENODE_IS(funcref, EOBJREF)) {
- Object *func = funcref->data.objref;
- if (CExcept_CanThrowException(func, func->datatype == DVFUNC && !(expr->flags & ENODE_FLAG_80)))
- cexcept_canthrow = 1;
- } else {
- cexcept_canthrow = 1;
- }
-}
-
-static Boolean CExcept_CanThrowCheck(Object *func, Statement *stmt) {
- cexcept_canthrow = 0;
-
- while (stmt) {
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- 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_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- CExpr_SearchExprTree(stmt->expr, CExcept_HasFuncCallCallBack, 2, EFUNCCALL, EFUNCCALLP);
- break;
- default:
- CError_FATAL(2687);
- }
- stmt = stmt->next;
- }
-
- if (!cexcept_canthrow) {
- TYPE_FUNC(cscope_currentfunc->type)->flags |= FUNC_NOTHROW;
- return 0;
- } else {
- return 1;
- }
-}
-
-void CExcept_ExceptionTansform(Statement *stmt) {
- cexcept_uniqueobjs = NULL;
- CExcept_CleanupExceptionActions(stmt);
-
- if (cscope_currentfunc && CExcept_CanThrowCheck(cscope_currentfunc, stmt)) {
- CError_ASSERT(2716, IS_TYPE_FUNC(cscope_currentfunc->type));
- if (TYPE_FUNC(cscope_currentfunc->type)->exspecs && copts.exceptions)
- CExcept_InsertSpecificationActions(stmt, TYPE_FUNC(cscope_currentfunc->type)->exspecs);
- }
-}