diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CFunc.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-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/CFunc.c')
-rw-r--r-- | compiler_and_linker/unsorted/CFunc.c | 3224 |
1 files changed, 0 insertions, 3224 deletions
diff --git a/compiler_and_linker/unsorted/CFunc.c b/compiler_and_linker/unsorted/CFunc.c deleted file mode 100644 index 38cfab3..0000000 --- a/compiler_and_linker/unsorted/CFunc.c +++ /dev/null @@ -1,3224 +0,0 @@ -#include "compiler/CFunc.h" -#include "compiler/CABI.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CException.h" -#include "compiler/CExpr.h" -#include "compiler/CInit.h" -#include "compiler/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CSOM.h" -#include "compiler/CTemplateTools.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/Exceptions.h" -#include "compiler/FuncLevelAsmPPC.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/ObjGenMachO.h" -#include "compiler/Switch.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/types.h" - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -struct CFuncSave { - CScopeSave scope; - ObjectList *arguments; - ObjectList *locals; - CLabel *labels; - Statement *curstmt; - DeclBlock *firstblock; - DeclBlock *currentblock; - ExceptionAction *cexcept_dobjstack; - CLabel *sinit_label; - ENode *ainit_expr; - CtorChain *ctor_chain; - ParserTryBlock *trychain; - TempNodeCB cinit_tempnodefunc; - HashNameNode *tkidentifier; - Object *sinit_first_object; - FileOffsetInfo cparser_fileoffset; - TStreamElement symdecltoken; - SInt32 functionbodyoffset; - HashNameNode *functionbodypath; - SInt32 symdecloffset; - SInt32 symdeclend; - SInt32 sourceoffset; - HashNameNode *sourcefilepath; - SInt32 curstmtvalue; - NameObjCheckCB name_obj_check; - FuncArg *check_arglist; - short blockcount; - short localcount; - short tk; - AccessType global_access; - Boolean cexcept_hasdobjects; - Boolean ainit_only_one; - Boolean cfunc_is_extern_c; - Boolean temp_reference_init; -}; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -FuncArg elipsis; -FuncArg oldstyle; -ObjectList *arguments; -ObjectList *locals; -short localcount; -SInt32 curstmtvalue; -SInt32 sourceoffset; -HashNameNode *sourcefilepath; -SInt32 functionbodyoffset; -HashNameNode *functionbodypath; -InitExpr *init_expressions; -CLabel *Labels; -CtorChain *ctor_chain; -Statement *curstmt; -static short temp_destructor_object_regmem; -static short temp_destructor_objects; -static short temp_expression_has_conditionals; -static DeclBlock *firstblock; -static DeclBlock *currentblock; -static short blockcount; -static Object *sinit_first_object; -static CLabel *sinit_label; -static Boolean ainit_only_one; -static ENode *ainit_expr; -static FuncArg *check_arglist; -static Boolean cfunc_is_extern_c; -static short cfunc_staticvarcount; -static void *destroyobjects; -static Boolean cfunc_hasdtortemp; - -// forward decls -static void statement(DeclThing *thing); - -static void CFunc_LoopIncrement(void) { - if (curstmtvalue >= 0x1000) { - if (curstmtvalue >= 0xF000) - curstmtvalue++; - else - curstmtvalue += 0x1000; - } else { - curstmtvalue <<= 3; - } -} - -static void CFunc_LoopDecrement(void) { - if (curstmtvalue > 0x1000) { - if (curstmtvalue > 0xF000) - curstmtvalue--; - else - curstmtvalue -= 0x1000; - } else { - curstmtvalue >>= 3; - } - - if (curstmtvalue < 1) - curstmtvalue = 1; -} - -DeclBlock *CFunc_NewDeclBlock(void) { - DeclBlock *block; - NameSpace *nspace; - - block = lalloc(sizeof(DeclBlock)); - if (firstblock) { - currentblock->next = block; - currentblock = block; - } else { - firstblock = block; - currentblock = block; - } - - block->index = blockcount++; - block->parent_nspace = cscope_current; - block->dobjstack = cexcept_dobjstack; - - nspace = CScope_NewListNameSpace(NULL, 0); - nspace->parent = cscope_current; - cscope_current = nspace; - - return block; -} - -void CFunc_RestoreBlock(DeclBlock *block) { - if (curstmt && curstmt->dobjstack != cexcept_dobjstack) { - Statement *stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = nullnode(); - } - - cscope_current = block->parent_nspace; - cexcept_dobjstack = block->dobjstack; -} - -void CFunc_SetupLocalVarInfo(Object *obj) { - obj->u.var.info = CodeGen_GetNewVarInfo(); - obj->u.var.info->func = cscope_currentfunc; - - if (obj->sclass == TK_REGISTER) { - if (!copts.optimizesize) - obj->u.var.info->usage = 100; - else - obj->u.var.info->usage = 5; - } - - if (obj->type && is_volatile_object(obj)) - obj->u.var.info->noregister = 1; -} - -static void adjustargumenttype(DeclInfo *declinfo) { - switch (declinfo->thetype->type) { - case TYPECLASS: - if (TYPE_CLASS(declinfo->thetype)->sominfo) { - CError_Error(CErrorStr284); - declinfo->thetype = TYPE(&stsignedint); - } - break; - case TYPEFUNC: - makethetypepointer(declinfo, 0); - return; - case TYPEARRAY: - declinfo->thetype = CDecl_NewPointerType(TPTR_TARGET(declinfo->thetype)); - return; - case TYPETEMPLATE: - if (TYPE_TEMPLATE(declinfo->thetype)->dtype == TEMPLDEP_ARRAY) - declinfo->thetype = CDecl_NewPointerType(TYPE_TEMPLATE(declinfo->thetype)->u.array.type); - return; - } - - if (!CanCreateObject(declinfo->thetype)) - declinfo->thetype = TYPE(&stsignedint); -} - -static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) { - while (list) { - if (name == list->name) - return list; - list = list->next; - } - - return NULL; -} - -static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) { - while (list) { - if (name == list->object->name) - return list->object; - list = list->next; - } - - return NULL; -} - -static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) { - FuncArg *tail; - - if ((tail = *list)) { - while (tail->next) - tail = tail->next; - tail->next = arg; - } else { - *list = arg; - } -} - -static void identifier_list(DeclInfo *declinfo) { - FuncArg *arg; - - declinfo->x45 = 1; - - while (1) { - if (tk != TK_IDENTIFIER) { - CError_Error(CErrorStr121); - } else { - if (CFunc_IsInArgList(declinfo->x18, tkidentifier)) - CError_Error(CErrorStr122, tkidentifier->name); - - arg = CParser_NewFuncArg(); - arg->name = tkidentifier; - CFunc_AppendArg(&declinfo->x18, arg); - declinfo->x44 = 1; - } - - if ((tk = lex()) != ',') - break; - tk = lex(); - } -} - -static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) { - FuncArg *arg; - - if (name) { - for (arg = check_arglist; arg; arg = arg->next) { - if (arg->name == name) { - CError_Error(CErrorStr205); - return 0; - } - } - } - - if (obj && obj->datatype == DLOCAL) { - CError_Error(CErrorStr205); - return 0; - } - - return 1; -} - -ENode *CFunc_DefaultArg(Type *type, UInt32 qual, FuncArg *args) { - TStreamElement *element; - ENode *expr; - ENode *templdepexpr; - - name_obj_check = defarg_name_obj_check; - check_arglist = args; - expr = conv_assignment_expression(); - name_obj_check = NULL; - - if ( - !CTemplTool_IsTemplateArgumentDependentExpression(expr) && - !CTemplTool_IsTemplateArgumentDependentType(type) - ) - { - expr = argumentpromotion(expr, type, qual, 1); - } else { - element = CPrep_CurStreamElement(); - if (element && element->tokenfile) { - templdepexpr = CExpr_NewTemplDepENode(TDE_SOURCEREF); - templdepexpr->data.templdep.u.sourceref.expr = expr; - templdepexpr->data.templdep.u.sourceref.token = galloc(sizeof(TStreamElement)); - *templdepexpr->data.templdep.u.sourceref.token = *element; - expr = templdepexpr; - } - } - - return CInline_CopyExpression(expr, CopyMode1); -} - -static FuncArg *parameter_list(DeclInfo *declinfo) { - Boolean flag26; - FuncArg *args; - FuncArg *arg; - DeclInfo my_di; - Boolean isArray; - - args = NULL; - flag26 = 1; - - while (1) { - if (tk == TK_ELLIPSIS) { - if (flag26) { - if (!copts.cplusplus && copts.ANSIstrict) - CError_Warning(CErrorStr127); - args = &elipsis; - } else { - CFunc_AppendArg(&args, &elipsis); - } - - tk = lex(); - return args; - } - - memclrw(&my_di, sizeof(my_di)); - CParser_GetDeclSpecs(&my_di, 0); - if (my_di.x48) - CError_Error(CErrorStr127); - - if ( - my_di.storageclass && - my_di.storageclass != TK_REGISTER && - (!copts.cplusplus || my_di.storageclass != TK_AUTO) - ) - { - CError_Error(CErrorStr127); - my_di.storageclass = 0; - } - - my_di.name = NULL; - - scandeclarator(&my_di); - - if (flag26) { - flag26 = 0; - if (my_di.thetype == &stvoid) { - if (my_di.storageclass || my_di.qual || my_di.name) - CError_Error(CErrorStr127); - return NULL; - } - } - - isArray = IS_TYPE_ARRAY(my_di.thetype); - adjustargumenttype(&my_di); - - if (my_di.name) { - if (args && CFunc_IsInArgList(args, my_di.name)) - CError_Error(CErrorStr122, my_di.name->name); - } else { - my_di.name = no_name_node; - } - - if (my_di.thetype == &stvoid) - CError_Error(CErrorStr126); - - arg = CParser_NewFuncArg(); - arg->name = my_di.name; - arg->type = my_di.thetype; - arg->qual = my_di.qual; - arg->sclass = my_di.storageclass; - arg->is_array = isArray; - CFunc_AppendArg(&args, arg); - - if (copts.cplusplus && tk == '=') { - tk = lex(); - arg->dexpr = CFunc_DefaultArg(arg->type, arg->qual, args); - } - - if (tk != ',') { - if (tk != TK_ELLIPSIS || !copts.cplusplus) - return args; - } else { - tk = lex(); - } - } -} - -Boolean CFunc_ParseFakeArgList(Boolean flag) { - DeclInfo di; - - if (tk == TK_ELLIPSIS) - return 1; - - do { - memclrw(&di, sizeof(di)); - CParser_GetDeclSpecs(&di, 0); - - if (di.x48) - return 0; - - scandeclarator(&di); - - if (tk == '=') { - tk = lex(); - assignment_expression(); - } - - switch (tk) { - case TK_ELLIPSIS: - return 1; - case ',': - if (!flag) - tk = lex(); - else - return 1; - break; - default: - return 0; - } - } while (tk != TK_ELLIPSIS); - - return 1; -} - -FuncArg *parameter_type_list(DeclInfo *declinfo) { - FuncArg *args; - NameSpace *nspace; - Boolean save_in_func_arglist; - - declinfo->x44 = 0; - declinfo->x45 = 0; - declinfo->x1C = NULL; - - if (tk == TK_ELLIPSIS || isdeclaration(0, 0, 0, 0)) { - if (!copts.cplusplus) { - nspace = CScope_NewListNameSpace(NULL, 0); - nspace->parent = cscope_current; - cscope_current = nspace; - - save_in_func_arglist = in_func_arglist; - in_func_arglist = 1; - args = parameter_list(declinfo); - in_func_arglist = save_in_func_arglist; - - cscope_current = nspace->parent; - - if (!CScope_IsEmptyNameSpace(nspace)) - declinfo->x1C = nspace; - } else { - args = parameter_list(declinfo); - } - } else if (copts.cplusplus) { - args = NULL; - if (tk != ')') - CError_Error(CErrorStr127); - } else { - identifier_list(declinfo); - args = &oldstyle; - } - - return args; -} - -CLabel *findlabel(void) { - CLabel *scan; - - for (scan = Labels; scan; scan = scan->next) { - if (tkidentifier == scan->name) - return scan; - } - - return NULL; -} - -CLabel *newlabel(void) { - CLabel *label = lalloc(sizeof(CLabel)); - memclrw(label, sizeof(CLabel)); - - label->name = label->uniquename = CParser_GetUniqueName(); - return label; -} - -Statement *CFunc_AppendStatement(StatementType sttype) { - Statement *stmt = lalloc(sizeof(Statement)); - - stmt->next = NULL; - stmt->type = sttype; - stmt->value = curstmtvalue; - stmt->flags = 0; - stmt->sourceoffset = sourceoffset; - stmt->sourcefilepath = sourcefilepath; - stmt->dobjstack = cexcept_dobjstack; - - curstmt->next = stmt; - curstmt = stmt; - return stmt; -} - -Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) { - Statement *stmt = lalloc(sizeof(Statement)); - - stmt->next = after->next; - after->next = stmt; - stmt->type = sttype; - stmt->value = after->value; - stmt->flags = 0; - stmt->sourceoffset = after->sourceoffset; - stmt->sourcefilepath = after->sourcefilepath; - stmt->dobjstack = after->dobjstack; - - return stmt; -} - -Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) { - Statement *stmt = lalloc(sizeof(Statement)); - - *stmt = *before; - before->next = stmt; - before->type = sttype; - before->flags = 0; - - return before; -} - -void CheckCLabels(void) { - CLabel *scan; - - for (scan = Labels; scan; scan = scan->next) { - if (!scan->stmt) - CError_Error(CErrorStr159, scan->name->name); - } -} - -Object *create_temp_object(Type *type) { - Object *object = CParser_NewLocalDataObject(NULL, 1); - object->name = CParser_GetUniqueName(); - object->type = type; - CFunc_SetupLocalVarInfo(object); - return object; -} - -ENode *create_temp_node(Type *type) { - ENode *node; - - if (cinit_tempnodefunc) - return cinit_tempnodefunc(type, 0); - - node = CExpr_NewETEMPNode(type, 0); - if (IS_TYPE_CLASS(type) && CClass_Destructor(TYPE_CLASS(type))) - node->data.temp.needs_dtor = 1; - return node; -} - -ENode *create_temp_node2(Type *type) { - ENode *node; - - if (cinit_tempnodefunc) - return cinit_tempnodefunc(type, 1); - - node = CExpr_NewETEMPNode(type, 0); - node->data.temp.needs_dtor = 1; - return node; -} - -static ENode *CFunc_DestroyReverse(ENode *expr, DtorTemp *list) { - expr = makediadicnode(expr, CABI_DestroyObject(list->dtor, create_objectrefnode(list->object), CABIDestroy1, 1, 0), ECOMMA); - expr->rtype = &stvoid; - if (list->next) - expr = CFunc_DestroyReverse(expr, list->next); - return expr; -} - -static ENode *CFunc_TempTransDestroy(ENode *expr, DtorTemp *list, Boolean flag) { - Object *tempobj; - - if (flag) { - CError_ASSERT(738, !(IS_TYPE_CLASS(expr->rtype) && CClass_Destructor(TYPE_CLASS(expr->rtype)))); - tempobj = create_temp_object(expr->rtype); - expr = makediadicnode(create_objectnode(tempobj), expr, EASS); - } - - expr = CFunc_DestroyReverse(expr, list); - - if (flag) { - expr = makediadicnode(expr, create_objectnode(tempobj), ECOMMA); - expr->rtype = tempobj->type; - } - - return expr; -} - -void CFunc_WarnUnused(void) { - if (copts.warn_unusedvar) { - ObjectList *list; - for (list = locals; list; list = list->next) { - if ( - !(list->object->flags & OBJECT_USED) && - !IsTempName(list->object->name) && - !(list->object->qual & Q_INLINE_DATA) - ) - { - CError_SetErrorToken(&list->object->u.var.info->deftoken); - CError_Warning(CErrorStr182, &list->object->name->name); - } - } - } - - if (copts.warn_unusedarg) { - ObjectList *list; - for (list = arguments; list; list = list->next) { - if ( - !(list->object->flags & OBJECT_USED) && - !IsTempName(list->object->name) && - list->object->name != this_name_node && - list->object->name != self_name_node - ) - { - CError_SetErrorToken(&symdecltoken); - CError_Warning(CErrorStr182, &list->object->name->name); - } - } - } -} - -void CFunc_CodeCleanup(Statement *stmt) { - if (cscope_currentclass && cscope_currentclass->sominfo) - CSOM_InitSOMSelf(cscope_currentclass, stmt); - - CFunc_WarnUnused(); - CExcept_ExceptionTansform(stmt); -} - -static Boolean DestructorNeeded(ExceptionAction *ea, ExceptionAction *end) { - while (ea) { - if (CExcept_ActionNeedsDestruction(ea)) - return 1; - if (ea == end) - break; - ea = ea->prev; - } - - return 0; -} - -static Statement *DestructLocals(Statement *stmt, ExceptionAction *ea, ExceptionAction *end) { - while (ea) { - stmt = CExcept_ActionCleanup(ea, stmt); - if (ea == end) - break; - ea = ea->prev; - } - - return stmt; -} - -static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) { - ExceptionAction *ea2; - ExceptionAction *ea1; - ExceptionAction *scan; - - ea1 = stmt1->dobjstack; - ea2 = stmt2->dobjstack; - - for (scan = ea2; scan; scan = scan->prev) { - if (scan == ea1) - return 0; - } - - while (ea1 && ea1 != ea2) { - if (CExcept_ActionNeedsDestruction(ea1)) - return 1; - ea1 = ea1->prev; - } - - return 0; -} - -static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) { - ExceptionAction *ea1; - ExceptionAction *ea2; - - for (ea2 = stmt2->dobjstack; ea2; ea2 = ea2->prev) { - for (ea1 = stmt1->dobjstack; ea1; ea1 = ea1->prev) { - if (ea1->prev == ea2) - return ea1; - } - } - - return NULL; -} - -static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) { - Statement *stmt; - Object *tempobj; - - if (stmt1->dobjstack != stmt2->dobjstack && NeedsDestruction(stmt1, stmt2)) - stmt1 = DestructLocals(stmt1, stmt1->dobjstack, FindLastNonCommonStackObj(stmt1, stmt2)); - - if (DestructorNeeded(stmt2->dobjstack, NULL)) { - if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) != 1) { - tempobj = create_temp_object(stmt2->expr->rtype); - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1); - stmt->expr = makediadicnode(create_objectnode(tempobj), stmt2->expr, EASS); - stmt->sourceoffset = stmt2->sourceoffset; - stmt->sourcefilepath = stmt2->sourcefilepath; - DestructLocals(stmt, stmt2->dobjstack, NULL); - stmt2->expr = create_objectnode(tempobj); - } else { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1); - stmt->expr = stmt2->expr; - stmt->sourceoffset = stmt2->sourceoffset; - stmt->sourcefilepath = stmt2->sourcefilepath; - DestructLocals(stmt, stmt2->dobjstack, NULL); - stmt2->expr = nullnode(); - } - } -} - -static Statement *DestructorIfTransform(Statement *stmt) { - CLabel *label; - Statement *newStmt; - - if (stmt->type == ST_IFGOTO) - stmt->type = ST_IFNGOTO; - else - stmt->type = ST_IFGOTO; - - label = newlabel(); - newStmt = DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, stmt->label->stmt)); - newStmt = CFunc_InsertStatement(ST_GOTO, newStmt); - newStmt->label = stmt->label; - newStmt = CFunc_InsertStatement(ST_LABEL, newStmt); - newStmt->label = label; - label->stmt = newStmt; - stmt->label = label; - newStmt->dobjstack = stmt->dobjstack; - return newStmt; -} - -static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) { - if (!exc1) - return 1; - - while (exc2) { - if (exc2 == exc1) - return 1; - exc2 = exc2->prev; - } - - return 0; -} - -static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) { - if (stmt->dobjstack != exc && !IsSubStack(exc, stmt->dobjstack)) { - while (exc) { - if (CExcept_ActionNeedsDestruction(exc) && exc->type != EAT_ACTIVECATCHBLOCK) { - CError_Warning(CErrorStr211); - break; - } - exc = exc->prev; - } - } -} - -void CFunc_DestructorCleanup(Statement *stmt) { - Statement *scan; - Statement *next; - SwitchCase *swcase; - - if (copts.cplusplus) { - for (scan = stmt; scan; scan = scan->next) { - switch (scan->type) { - case ST_NOP: - case ST_LABEL: - case ST_EXPRESSION: - case ST_RETURN: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_GOTOEXPR: - case ST_ASM: - break; - case ST_SWITCH: - CFunc_CheckInitSkip(scan, ((SwitchInfo *) scan->label)->defaultlabel->stmt->dobjstack); - for (swcase = ((SwitchInfo *) scan->label)->cases; swcase; swcase = swcase->next) { - CFunc_CheckInitSkip(scan, swcase->label->stmt->dobjstack); - } - break; - case ST_GOTO: - case ST_IFGOTO: - case ST_IFNGOTO: - CFunc_CheckInitSkip(scan, scan->label->stmt->dobjstack); - break; - default: - CError_FATAL(1045); - } - } - - if (cexcept_hasdobjects) { - while (1) { - next = stmt->next; - if (!next) { - if (stmt->type != ST_RETURN && stmt->dobjstack) - DestructLocals(stmt, stmt->dobjstack, NULL); - return; - } - - switch (next->type) { - case ST_GOTO: - if ( - stmt->dobjstack != next->label->stmt->dobjstack && - NeedsDestruction(stmt, next->label->stmt) - ) - { - DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next->label->stmt)); - } - stmt = next; - continue; - - case ST_RETURN: - if (next->expr && DestructorNeeded(stmt->dobjstack, NULL)) { - DestructorReturnTransform(stmt, next); - } else if (stmt->dobjstack) { - DestructLocals(stmt, stmt->dobjstack, NULL); - } - stmt = next; - continue; - } - - switch (stmt->type) { - case ST_GOTO: - case ST_SWITCH: - case ST_RETURN: - case ST_GOTOEXPR: - break; - case ST_NOP: - case ST_LABEL: - case ST_EXPRESSION: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_ASM: - if ( - stmt->dobjstack != next->dobjstack && - NeedsDestruction(stmt, next) - ) - { - DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next)); - } - break; - default: - CError_FATAL(1109); - } - - switch (next->type) { - case ST_NOP: - case ST_LABEL: - case ST_EXPRESSION: - case ST_SWITCH: - case ST_BEGINCATCH: - case ST_ENDCATCH: - case ST_ENDCATCHDTOR: - case ST_ASM: - stmt = next; - continue; - - case ST_IFGOTO: - case ST_IFNGOTO: - if ( - next->dobjstack != next->label->stmt->dobjstack && - NeedsDestruction(next, next->label->stmt) - ) - { - stmt = DestructorIfTransform(next); - } else { - stmt = next; - } - break; - - default: - CError_FATAL(1138); - } - } - } - } -} - -static void scancase(DeclThing *thing) { - SwitchCase *swcase; - Statement *stmt; - CInt64 min; - CInt64 max; - - if (!thing->switchinfo) { - CError_Error(CErrorStr169); - return; - } - - tk = lex(); - min = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr()); - if (!copts.ANSIstrict && tk == TK_ELLIPSIS) { - tk = lex(); - max = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr()); - if (CInt64_Greater(min, max)) - CError_Error(CErrorStr366); - if (thing->switchinfo->x8->size == stsignedlonglong.size) - CError_Error(CErrorStr368); - } else { - max = min; - } - - for (swcase = thing->switchinfo->cases; swcase; swcase = swcase->next) { - if (CInt64_GreaterEqual(swcase->min, min) && CInt64_LessEqual(swcase->min, max)) - CError_Error(CErrorStr172); - if (CInt64_GreaterEqual(swcase->max, min) && CInt64_LessEqual(swcase->max, max)) - CError_Error(CErrorStr172); - if (CInt64_Less(swcase->min, min) && CInt64_Greater(swcase->max, max)) - CError_Error(CErrorStr172); - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = newlabel(); - stmt->label->stmt = stmt; - - swcase = lalloc(sizeof(SwitchCase)); - swcase->min = min; - swcase->label = stmt->label; - swcase->next = thing->switchinfo->cases; - thing->switchinfo->cases = swcase; - swcase->max = max; - - if (tk != ':') - CError_ErrorSkip(CErrorStr170); - else - tk = lex(); - - statement(thing); -} - -static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) { - char buf[64]; - HashNameNode *name; - - if (!(cscope_currentfunc && (cscope_currentfunc->qual & Q_INLINE)) || CParser_HasInternalLinkage(cscope_currentfunc)) { - obj->name = CParser_AppendUniqueName(str); - } else { - sprintf(buf, "$localstatic%" PRId32 "$", cfunc_staticvarcount++); - name = CMangler_GetLinkName(cscope_currentfunc); - name = CParser_NameConcat(buf, name->name); - name = CParser_NameConcat(str, name->name); - obj->name = name; - obj->qual |= Q_20000; - obj->sclass = 0; - } -} - -static void sinit_insert_expr(ENode *expr) { - Statement *stmt; - - if (!sinit_first_object) { - sinit_first_object = CParser_NewCompilerDefDataObject(); - sinit_first_object->type = TYPE(&stsignedchar); - sinit_first_object->sclass = TK_STATIC; - CFunc_NameLocalStaticDataObject(sinit_first_object, "init"); - CInit_DeclareData(sinit_first_object, NULL, NULL, sinit_first_object->type->size); - - sinit_label = newlabel(); - stmt = CFunc_AppendStatement(ST_IFGOTO); - stmt->expr = create_objectnode(sinit_first_object); - stmt->label = sinit_label; - } - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; -} - -static void ainit_insert_expr(ENode *expr) { - Statement *stmt; - - if (ainit_only_one) { - if (ainit_expr) { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = ainit_expr; - } - ainit_expr = expr; - } else { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; - } -} - -static ENode *ainit_register_object(Type *type, Object *local, SInt32 offset, Boolean flag) { - return CExcept_RegisterDestructorObject(local, offset, CClass_Destructor(TYPE_CLASS(type)), flag); -} - -static void CFunc_LocalDataDeclarator(DeclInfo *di, TStreamElement *deftoken, Boolean flag1, Boolean flag2) { - Object *object; - Object *aliasObject; - NameSpace *globalNS; - NameSpaceObjectList *nsol; - NameSpaceName *nsname; - Statement *stmt; - - if (di->nspace) - CError_Error(CErrorStr121); - - CDecl_CompleteType(di->thetype); - - object = NULL; - - if ((nsol = CScope_FindName(cscope_current, di->name))) { - switch (nsol->object->otype) { - case OT_OBJECT: - object = OBJECT(nsol->object); - break; - case OT_NAMESPACE: - CError_Error(CErrorStr321); - return; - case OT_ENUMCONST: - case OT_TYPE: - CError_Error(CErrorStr322); - break; - case OT_TYPETAG: - break; - default: - CError_FATAL(1344); - } - } - - if (object) - CError_Error(CErrorStr333, object); - - if (di->storageclass == TK_EXTERN) { - object = NULL; - globalNS = CScope_FindGlobalNS(cscope_current); - if ((nsol = CScope_FindName(globalNS, di->name))) { - switch (nsol->object->otype) { - case OT_OBJECT: - object = OBJECT(nsol->object); - break; - case OT_NAMESPACE: - CError_Error(CErrorStr321); - return; - case OT_ENUMCONST: - case OT_TYPE: - CError_Error(CErrorStr322); - break; - case OT_TYPETAG: - break; - default: - CError_FATAL(1381); - } - } - - if (object) { - if ( - !is_typesame(di->thetype, object->type) || - (di->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK)) != (object->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK)) - ) - { - CError_Error(CErrorStr249, di->name->name, object->type, object->qual, di->thetype, di->qual); - } - } else { - object = CParser_NewGlobalDataObject(di); - object->nspace = globalNS; - } - - CParser_NewAliasObject(object, 0); - return; - } - - if (di->storageclass != TK_STATIC) - object = CParser_NewObject(di); - else - object = CParser_NewGlobalDataObject(di); - - object->name = di->name; - object->type = di->thetype; - object->qual = di->qual; - object->sclass = di->storageclass; - - switch (di->storageclass) { - case TK_STATIC: - if (flag1) { - CError_Error(CErrorStr177); - return; - } - if (flag2) - CError_Error(CErrorStr174); - - if (CanCreateObject(di->thetype)) { - CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK)); - CParser_NewAliasObject(object, 0); - object->nspace = cscope_root; - object->datatype = DDATA; - CFunc_NameLocalStaticDataObject(object, object->name->name); - - if (copts.cplusplus) { - sinit_first_object = NULL; - CInit_InitializeStaticData(object, sinit_insert_expr); - if (sinit_first_object) { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = makediadicnode( - create_objectnode(sinit_first_object), - intconstnode(TYPE(&stsignedchar), 1), - EASS); - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = sinit_label; - sinit_label->stmt = stmt; - } - } else { - CInit_InitializeData(object); - } - } - break; - - case 0: - case TK_AUTO: - case TK_REGISTER: - if (CanCreateObject(di->thetype)) { - CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK)); - object->datatype = DLOCAL; - CFunc_SetupLocalVarInfo(object); - - object->u.var.info->deftoken = *deftoken; - if (object->sclass == TK_REGISTER && flag1) - object->u.var.info->usage = 100; - - CScope_AddObject(cscope_current, object->name, OBJ_BASE(object)); - - if (!flag1) { - if (IS_TYPE_SOM_CLASS(di->thetype)) { - CSOM_InitAutoClass(object); - } else { - CInit_InitializeAutoData(object, ainit_insert_expr, ainit_register_object); - if (object->type != di->thetype && (IS_TYPE_STRUCT(object->type) || IS_TYPE_CLASS(object->type))) { - CError_ASSERT(1478, !cscope_current->is_hash); - CError_ASSERT(1479, nsname = CScope_FindNameSpaceName(cscope_current, object->name)); - CError_ASSERT(1480, nsname->first.object == OBJ_BASE(object)); - CError_ASSERT(1481, !nsname->first.next); - nsname->name = CParser_AppendUniqueName(object->name->name); - - aliasObject = CParser_NewAliasObject(object, 0); - aliasObject->type = di->thetype; - } - } - } - - if (object->datatype == DLOCAL) { - ObjectList *list = lalloc(sizeof(ObjectList)); - list->object = object; - list->next = locals; - locals = list; - } - - IsCompleteType(di->thetype); - } - break; - - default: - CError_FATAL(1504); - } -} - -static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) { - Type *type; - UInt32 qual; - DeclInfo di; - TStreamElement deftoken; - - ainit_expr = NULL; - ainit_only_one = flag2; - - while (flag2 || isdeclaration(copts.cplusplus, 0, 0, 0)) { - CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); - - memclrw(&di, sizeof(di)); - di.is_extern_c = cfunc_is_extern_c; - CParser_GetDeclSpecs(&di, 0); - - if (IS_TYPE_TEMPLATE(di.thetype)) { - CError_Error(CErrorStr146); - di.thetype = TYPE(&stsignedint); - } - - type = di.thetype; - qual = di.qual; - - if (tk != ';') { - while (1) { - deftoken = *CPrep_CurStreamElement(); - di.name = NULL; - scandeclarator(&di); - - if (di.name) { - if (di.storageclass != TK_TYPEDEF) { - if (IS_TYPE_FUNC(di.thetype)) { - if (!CDecl_FunctionDeclarator(&di, CScope_FindGlobalNS(cscope_current), 0, 0)) - break; - } else { - CFunc_LocalDataDeclarator(&di, &deftoken, flag1, flag2); - } - } else { - CDecl_TypedefDeclarator(&di); - } - } else { - CError_Error(CErrorStr134); - } - - if (tk == ';') - break; - - if (tk != ',') { - if (!flag2) - CError_Error(CErrorStr123); - break; - } - - di.nspace = NULL; - di.thetype = type; - di.qual = qual; - tk = lex(); - } - } else { - CParser_CheckAnonymousUnion(&di, 1); - } - - if (flag2) - break; - if (flag4) - break; - tk = lex(); - } - - if (flag2) { - if (!ainit_expr) { - if (!flag3) { - CError_Error(CErrorStr141); - ainit_expr = nullnode(); - } - } else { - ainit_expr = checkreference(ainit_expr); - } - } - - return ainit_expr; -} - -static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) { - Statement *stmt; - CLabel *tmplabel; - - if (!expr) { - if (flag1) { - stmt = CFunc_AppendStatement(ST_GOTO); - stmt->label = label1; - return; - } - return; - } - - if ( - ENODE_IS(expr, ETYPCON) && - IS_TYPE_INT(expr->rtype) && - IS_TYPE_INT(expr->data.monadic->rtype) && - expr->rtype->size >= expr->data.monadic->rtype->size - ) - expr = expr->data.monadic; - - if (isnotzero(expr)) { - if (flag1) { - stmt = CFunc_AppendStatement(ST_GOTO); - stmt->label = label1; - return; - } - return; - } - - if (iszero(expr)) { - if (!flag1) { - stmt = CFunc_AppendStatement(ST_GOTO); - stmt->label = label1; - return; - } - return; - } - - if (ENODE_IS(expr, ELOGNOT)) { - makeifstatement(expr->data.monadic, label1, label2, !flag1, flag2); - return; - } - - if (ENODE_IS(expr, ELOR)) { - tmplabel = newlabel(); - if (flag1) { - makeifstatement(expr->data.diadic.left, label1, tmplabel, 1, flag2); - tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); - tmplabel->stmt->label = tmplabel; - makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2); - return; - } else { - makeifstatement(expr->data.diadic.left, label2, tmplabel, 1, flag2); - tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); - tmplabel->stmt->label = tmplabel; - makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2); - return; - } - } - - if (ENODE_IS(expr, ELAND)) { - tmplabel = newlabel(); - if (flag1) { - makeifstatement(expr->data.diadic.left, label2, tmplabel, 0, flag2); - tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); - tmplabel->stmt->label = tmplabel; - makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2); - return; - } else { - makeifstatement(expr->data.diadic.left, label1, tmplabel, 0, flag2); - tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); - tmplabel->stmt->label = tmplabel; - makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2); - return; - } - } - - stmt = CFunc_AppendStatement(ST_IFGOTO); - stmt->label = label1; - stmt->expr = expr; - if (!flag1) - stmt->type = ST_IFNGOTO; - if (flag2) - stmt->flags = stmt->flags | StmtFlag_4; -} - -static void CFunc_HasDtorTempCallBack(ENode *expr) { - if (expr->data.temp.needs_dtor || expr->data.temp.uniqueid) - cfunc_hasdtortemp = 1; -} - -static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) { - Statement *stmt; - CLabel *tmplabel; - - if (expr && copts.cplusplus && copts.exceptions) { - cfunc_hasdtortemp = 0; - CExpr_SearchExprTree(expr, CFunc_HasDtorTempCallBack, 1, ETEMP); - if (cfunc_hasdtortemp) { - stmt = CFunc_AppendStatement(flag1 ? ST_IFGOTO : ST_IFNGOTO); - stmt->label = label; - stmt->expr = expr; - if (flag2) - stmt->flags = stmt->flags | StmtFlag_4; - return; - } - } - - tmplabel = newlabel(); - makeifstatement(expr, label, tmplabel, flag1, flag2); - tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); - tmplabel->stmt->label = tmplabel; -} - -Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *lowerBound, ENode *upperBound, ENode *increment1, ENode *increment2, ENode *(*callback)(ENode *, ENode *)) { - ENode *var1; - ENode *var2; - CLabel *label; - ENode *ind; - ENode *ind2; - Statement *s; - - var1 = CExpr_NewETEMPNode(type, 1); - ind = lalloc(sizeof(ENode)); - *ind = *var1; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - // initialise var1 to lowerBound - if (stmt) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_EXPRESSION); - } - s->expr = makediadicnode(ind, lowerBound, EASS); - - if (increment2) { - var2 = CExpr_NewETEMPNode(type, 1); - ind = lalloc(sizeof(ENode)); - *ind = *var2; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - // initialise var2 to upperBound - if (stmt) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_EXPRESSION); - } - s->expr = makediadicnode(ind, upperBound, EASS); - } - - // label for loop body - label = newlabel(); - if (stmt) { - stmt = CFunc_InsertStatement(ST_LABEL, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_LABEL); - } - s->label = label; - label->stmt = s; - - if (callback) { - ind = lalloc(sizeof(ENode)); - *ind = *var1; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - if (increment2) { - ind2 = lalloc(sizeof(ENode)); - *ind2 = *var2; - ind2 = makemonadicnode(ind2, EINDIRECT); - ind2->rtype = type; - } else { - ind2 = NULL; - } - - // generate a loop body - if ((ind = callback(ind, ind2))) { - if (stmt) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_EXPRESSION); - } - s->expr = ind; - } - } - - if (increment1) { - ind = lalloc(sizeof(ENode)); - *ind = *var1; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - // add increment1 to var1 - if (stmt) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_EXPRESSION); - } - s->expr = makediadicnode(ind, increment1, EADDASS); - - if (increment2) { - ind = lalloc(sizeof(ENode)); - *ind = *var2; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - // add increment2 to var2 - if (stmt) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_EXPRESSION); - } - s->expr = makediadicnode(ind, increment2, EADDASS); - } - } - - ind = lalloc(sizeof(ENode)); - *ind = *var1; - ind = makemonadicnode(ind, EINDIRECT); - ind->rtype = type; - - // loop if var1 < upperBound - if (stmt) { - stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); - s = stmt; - } else { - s = CFunc_AppendStatement(ST_IFGOTO); - } - s->expr = makediadicnode(ind, upperBound, ELESS); - s->expr->rtype = TYPE(&stbool); - s->label = label; - s->flags = StmtFlag_4; - - return stmt; -} - -static Boolean checklabel(void) { - HashNameNode *savename; - short savesize; - short token; - - savename = tkidentifier; - savesize = tksize; - token = lookahead(); - tkidentifier = savename; - tksize = savesize; - - return token == ':'; -} - -static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) { - Object *object; - ENode *expr2; - ENode *objexpr; - ObjectList *list; - ENodeList *exprlist; - - for (list = arguments; list; list = list->next) { - if (list->object->name == temp_argument_name) - break; - } - - CError_ASSERT(1907, list); - - object = list->object; - if ((expr2 = CExpr_IsTempConstruction(expr, type, &objexpr)) && ENODE_IS(objexpr, ETEMP)) { - *objexpr = *create_objectnode(object); - return expr2; - } - - if (IS_TYPE_CLASS(type)) { - expr2 = create_objectnode(object); - exprlist = lalloc(sizeof(ENodeList)); - exprlist->next = NULL; - exprlist->node = expr; - return CExpr_ConstructObject(TYPE_CLASS(type), expr2, exprlist, 1, 1, 0, 1, 0); - } - - expr2 = create_objectnode(object); - expr2 = makemonadicnode(expr2, EINDIRECT); - expr2->rtype = type; - - return makediadicnode(expr2, CExpr_AssignmentPromotion(expr, type, qual, 1), EASS); -} - -static void CFunc_AutoResultCheck(ENode *expr) { - while (1) { - while (ENODE_IS(expr, ECOMMA)) - expr = expr->data.diadic.right; - - switch (expr->type) { - case EOBJREF: - if (expr->data.objref->datatype != DLOCAL) - break; - case ETEMP: - CError_Warning(CErrorStr326); - break; - case EADD: - case ESUB: - CFunc_AutoResultCheck(expr->data.diadic.left); - expr = expr->data.diadic.right; - continue; - default: - break; - } - break; - } -} - -static void statement(DeclThing *thing) { - Statement *stmt; - Statement *stmt2; - CLabel *label; - DeclBlock *block; - ENode *expr; - HashNameNode *name; - DeclThing subthing; - - CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); - - switch (tk) { - case TK_RETURN: - tk = lex(); - if ( - (thing->thetype == &stvoid && !copts.cplusplus) || - CClass_IsConstructor(cscope_currentfunc) || - CClass_IsDestructor(cscope_currentfunc) - ) - { - if (tk != ';') { - CError_Error(CErrorStr315); - expression(); - } - - stmt = CFunc_AppendStatement(ST_RETURN); - stmt->expr = NULL; - CError_ResetErrorSkip(); - tk = lex(); - return; - } - - if (tk == ';') { - if (thing->thetype != &stvoid && (copts.pedantic || copts.cplusplus)) - CError_Warning(CErrorStr184); - - stmt = CFunc_AppendStatement(ST_RETURN); - stmt->expr = NULL; - CError_ResetErrorSkip(); - tk = lex(); - return; - } - - if (copts.old_argmatch) - expr = expression(); - else - expr = s_expression(); - - if (thing->thetype == &stvoid) { - if (expr->rtype != &stvoid) - CError_Error(CErrorStr315); - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; - - stmt = CFunc_AppendStatement(ST_RETURN); - stmt->expr = NULL; - } else { - if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) == 1) - expr = returnstatementadjust(expr, thing->thetype, thing->qual); - else - expr = CExpr_AssignmentPromotion(expr, thing->thetype, thing->qual, 1); - - stmt = CFunc_AppendStatement(ST_RETURN); - stmt->expr = expr; - - if (IS_TYPE_POINTER_ONLY(thing->thetype)) - CFunc_AutoResultCheck(expr); - } - - break; - - case TK_CASE: - scancase(thing); - return; - - case TK_DEFAULT: - if (!thing->switchinfo) { - CError_Error(CErrorStr169); - return; - } - - if (lex() != ':') - CError_ErrorSkip(CErrorStr170); - else - tk = lex(); - - if (thing->switchinfo->defaultlabel) - CError_ErrorSkip(CErrorStr173); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = newlabel(); - stmt->label->stmt = stmt; - thing->switchinfo->defaultlabel = stmt->label; - statement(thing); - return; - - case TK_SWITCH: - if (lex() != '(') - CError_ErrorSkip(CErrorStr114); - else - tk = lex(); - - if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) { - block = CFunc_NewDeclBlock(); - expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); - if (CScope_IsEmptyNameSpace(cscope_current)) { - CFunc_RestoreBlock(block); - block = NULL; - } - } else { - expr = expression(); - block = NULL; - } - - stmt = CFunc_AppendStatement(ST_SWITCH); - stmt->expr = CExpr_ConvertToIntegral(expr); - - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - - stmt->label = (CLabel *) lalloc(sizeof(SwitchInfo)); - ((SwitchInfo *) stmt->label)->defaultlabel = NULL; - ((SwitchInfo *) stmt->label)->cases = NULL; - ((SwitchInfo *) stmt->label)->x8 = stmt->expr->rtype; - - label = newlabel(); - subthing = *thing; - subthing.loopBreak = label; - subthing.switchinfo = (SwitchInfo *) stmt->label; - CFunc_CompoundStatement(&subthing); - - if (!subthing.switchinfo->defaultlabel) - subthing.switchinfo->defaultlabel = label; - - if (!subthing.switchinfo->cases) { - stmt->type = ST_EXPRESSION; - stmt2 = lalloc(sizeof(Statement)); - *stmt2 = *stmt; - stmt->next = stmt2; - stmt2->type = ST_GOTO; - stmt2->label = subthing.switchinfo->defaultlabel; - stmt2->dobjstack = cexcept_dobjstack; - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - if (block) - CFunc_RestoreBlock(block); - return; - - case TK_GOTO: - if ((tk = lex()) != TK_IDENTIFIER) { - if (tk == '*' && !copts.ANSIstrict) { - tk = lex(); - stmt = CFunc_AppendStatement(ST_GOTOEXPR); - stmt->expr = expression(); - if (!IS_TYPE_POINTER_ONLY(stmt->expr->rtype)) { - CError_Error(CErrorStr146); - stmt->expr = nullnode(); - stmt->expr->rtype = TYPE(&void_ptr); - } - } else { - CError_Error(CErrorStr107); - return; - } - } else { - stmt = CFunc_AppendStatement(ST_GOTO); - if (!(stmt->label = findlabel())) { - stmt->label = newlabel(); - stmt->label->next = Labels; - Labels = stmt->label; - stmt->label->name = tkidentifier; - } - tk = lex(); - } - break; - - case TK_BREAK: - if (thing->loopBreak) { - stmt = CFunc_AppendStatement(ST_GOTO); - stmt->label = thing->loopBreak; - } else { - CError_Error(CErrorStr169); - } - tk = lex(); - break; - - case TK_CONTINUE: - if (thing->loopContinue) { - stmt = CFunc_AppendStatement(ST_GOTO); - stmt->label = thing->loopContinue; - } else { - CError_Error(CErrorStr169); - } - tk = lex(); - break; - - case TK_FOR: { - CLabel *forLabel1; - CLabel *forLabel2; - CLabel *forLabel3; - ENode *forCond; - ENode *forInc; - - if (lex() != '(') - CError_ErrorSkip(CErrorStr114); - else - tk = lex(); - - block = NULL; - if (tk != ';') { - if (!copts.cplusplus || !isdeclaration(1, 0, 0, 0)) { - expr = expression(); - CExpr_CheckUnusedExpression(expr); - } else { - if (!copts.ARMscoping) - block = CFunc_NewDeclBlock(); - expr = CFunc_ParseLocalDeclarationList(0, 1, 1, 0); - if (block && CScope_IsEmptyNameSpace(cscope_current)) { - CFunc_RestoreBlock(block); - block = NULL; - } - } - - if (expr) { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; - } - - if (tk == ';') - CError_ResetErrorSkip(); - else - CError_Error(CErrorStr123); - } else { - CError_ResetErrorSkip(); - } - - if ((tk = lex()) != ';') { - if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) { - if (!block) - block = CFunc_NewDeclBlock(); - expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); - if (CScope_IsEmptyNameSpace(cscope_current)) { - CFunc_RestoreBlock(block); - block = NULL; - } - } else { - expr = expression(); - CExpr_CheckUnwantedAssignment(expr); - } - - forCond = CExpr_ConvertToCondition(expr); - - if (tk == ';') - CError_ResetErrorSkip(); - else - CError_Error(CErrorStr123); - } else { - CError_ResetErrorSkip(); - forCond = NULL; - } - - if ((tk = lex()) != ')') { - forInc = expression(); - CExpr_CheckUnusedExpression(forInc); - if (tk == ')') - CError_ResetErrorSkip(); - else - CError_Error(CErrorStr115); - } else { - CError_ResetErrorSkip(); - forInc = NULL; - } - - if (copts.warn_possunwant) { - spaceskip = 0; - if ((tk = lex()) == ';' && !spaceskip) - CError_Warning(CErrorStr206); - } else { - tk = lex(); - } - - if (forCond) { - stmt = CFunc_AppendStatement(ST_GOTO); - label = newlabel(); - stmt->label = label; - } else { - label = newlabel(); - } - - CFunc_LoopIncrement(); - - stmt = CFunc_AppendStatement(ST_LABEL); - forLabel1 = stmt->label = newlabel(); - forLabel1->stmt = stmt; - - forLabel2 = newlabel(); - forLabel3 = newlabel(); - - subthing = *thing; - subthing.loopContinue = forLabel3; - subthing.loopBreak = forLabel2; - - if (tk != '{') { - DeclBlock *b = CFunc_NewDeclBlock(); - CFunc_CompoundStatement(&subthing); - CFunc_RestoreBlock(b); - } else { - CFunc_CompoundStatement(&subthing); - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = forLabel3; - forLabel3->stmt = stmt; - - if (forInc) { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = forInc; - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; - - ifstatement(1, forCond, forLabel1, 1); - CFunc_LoopDecrement(); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = forLabel2; - forLabel2->stmt = stmt; - - if (block) - CFunc_RestoreBlock(block); - - return; - } - - case TK_DO: { - CLabel *label1; - CLabel *label2; - CLabel *label3; - - CFunc_LoopIncrement(); - stmt = CFunc_AppendStatement(ST_LABEL); - label1 = stmt->label = newlabel(); - label1->stmt = stmt; - - label2 = newlabel(); - label3 = newlabel(); - - subthing = *thing; - subthing.loopContinue = label2; - subthing.loopBreak = label3; - - tk = lex(); - CFunc_CompoundStatement(&subthing); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label2; - label2->stmt = stmt; - - if (tk != TK_WHILE) - CError_Error(CErrorStr105); - - if (lex() != '(') - CError_ErrorSkip(CErrorStr114); - else - tk = lex(); - - expr = CExpr_ConvertToCondition(expression()); - CExpr_CheckUnwantedAssignment(expr); - - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - - ifstatement(1, expr, label1, 1); - - CFunc_LoopDecrement(); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label3; - label3->stmt = stmt; - break; - } - - case TK_WHILE: { - CLabel *label1; - CLabel *label2; - CLabel *label3; - - if ((tk = lex()) != '(') - CError_ErrorSkip(CErrorStr114); - else - tk = lex(); - - if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) { - block = CFunc_NewDeclBlock(); - expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); - if (CScope_IsEmptyNameSpace(cscope_current)) { - CFunc_RestoreBlock(block); - block = NULL; - } - } else { - expr = expression(); - block = NULL; - CExpr_CheckUnwantedAssignment(expr); - } - expr = CExpr_ConvertToCondition(expr); - - if (tk != ')') { - CError_ErrorSkip(CErrorStr115); - } else { - if (copts.warn_possunwant) { - spaceskip = 0; - if ((tk = lex()) == ';' && !spaceskip) - CError_Warning(CErrorStr206); - } else { - tk = lex(); - } - } - - stmt = CFunc_AppendStatement(ST_GOTO); - label1 = newlabel(); - stmt->label = label1; - - CFunc_LoopIncrement(); - - stmt = CFunc_AppendStatement(ST_LABEL); - label2 = stmt->label = newlabel(); - label2->stmt = stmt; - - label3 = newlabel(); - - subthing = *thing; - subthing.loopContinue = label1; - subthing.loopBreak = label3; - - CFunc_CompoundStatement(&subthing); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label1; - label1->stmt = stmt; - - ifstatement(1, expr, label2, 1); - - CFunc_LoopDecrement(); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label3; - label3->stmt = stmt; - - if (block) - CFunc_RestoreBlock(block); - return; - } - - case TK_IF: { - CLabel *label1; - if ((tk = lex()) != '(') - CError_ErrorSkip(CErrorStr114); - else - tk = lex(); - - if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) { - block = CFunc_NewDeclBlock(); - expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); - if (CScope_IsEmptyNameSpace(cscope_current)) { - CFunc_RestoreBlock(block); - block = NULL; - } - } else { - expr = expression(); - block = NULL; - CExpr_CheckUnwantedAssignment(expr); - } - - expr = CExpr_ConvertToCondition(expr); - - label1 = newlabel(); - ifstatement(0, expr, label1, 0); - - if (tk != ')') { - CError_ErrorSkip(CErrorStr115); - } else { - if (copts.warn_possunwant) { - spaceskip = 0; - if ((tk = lex()) == ';' && !spaceskip) - CError_Warning(CErrorStr206); - } else { - tk = lex(); - } - } - - CFunc_CompoundStatement(thing); - - if (tk == TK_ELSE) { - if (copts.warn_possunwant) { - spaceskip = 0; - if ((tk = lex()) == ';' && !spaceskip) - CError_Warning(CErrorStr206); - } else { - tk = lex(); - } - - stmt = CFunc_AppendStatement(ST_GOTO); - label = stmt->label = newlabel(); - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label1; - label1->stmt = stmt; - - CFunc_CompoundStatement(thing); - - label1 = label; - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label1; - label1->stmt = stmt; - - if (block) - CFunc_RestoreBlock(block); - - return; - } - - case '{': - CFunc_CompoundStatement(thing); - return; - - case TK_ASM: - if (copts.cplusplus || !copts.ANSIstrict) { - tk = lex(); - volatileasm = 0; - - if (tk == TK_VOLATILE || (tk == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__volatile__"))) { - tk = lex(); - volatileasm = 1; - } - - if (tk == '(') { - InlineAsm_Assemble(); - if (tk == ')') { - tk = lex(); - break; - } else { - CError_Error(CErrorStr115); - return; - } - } - - if (tk == '{') { - InlineAsm_Assemble(); - if (tk != '}') { - CError_Error(CErrorStr130); - return; - } - if ((tk = lex()) == ';') - tk = lex(); - CError_ResetErrorSkip(); - return; - } - - CError_Error(CErrorStr114); - } else { - CError_Error(CErrorStr121); - } - return; - - case TK_TRY: - tk = lex(); - CExcept_ScanTryBlock(thing, 0); - return; - - case TK_USING: - if ((tk = lex()) == TK_NAMESPACE) { - tk = lex(); - CScope_ParseUsingDirective(cscope_current); - } else { - CScope_ParseUsingDeclaration(cscope_current, 0, 0); - } - return; - - case TK_NAMESPACE: - if ((tk = lex()) != TK_IDENTIFIER) { - CError_Error(CErrorStr107); - return; - } - name = tkidentifier; - if ((tk = lex()) != '=') { - CError_Error(CErrorStr121); - return; - } - - CScope_ParseNameSpaceAlias(name); - break; - - case ';': - break; - - case TK_IDENTIFIER: - if (checklabel()) { - stmt = CFunc_AppendStatement(ST_LABEL); - if ((stmt->label = findlabel())) { - if (stmt->label->stmt) - CError_Error(CErrorStr171, tkidentifier->name); - } else { - stmt->label = newlabel(); - stmt->label->next = Labels; - Labels = stmt->label; - stmt->label->name = tkidentifier; - } - - stmt->label->stmt = stmt; - tk = lex(); - tk = lex(); - statement(thing); - return; - } - tk = TK_IDENTIFIER; - - default: - if (copts.cplusplus && isdeclaration(1, 0, 0, 0)) { - CFunc_ParseLocalDeclarationList(0, 0, 0, 1); - tk = lex(); - return; - } - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expression(); - CExpr_CheckUnusedExpression(stmt->expr); - } - - if (tk == ';') { - CPrep_TokenStreamFlush(); - tk = lex(); - CError_ResetErrorSkip(); - } else { - CError_ErrorSkip(CErrorStr123); - } -} - -void CFunc_CompoundStatement(DeclThing *thing) { - DeclBlock *block; - - block = CFunc_NewDeclBlock(); - - if (tk == '{') { - tk = lex(); - if (!copts.cplusplus && isdeclaration(0, 0, 0, 0)) - CFunc_ParseLocalDeclarationList(0, 0, 0, 0); - - while (tk != '}') - statement(thing); - - CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); - tk = lex(); - } else { - statement(thing); - } - - CFunc_RestoreBlock(block); -} - -static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) { - Object *newobj; - Statement *stmt; - ENode *expr; - NameSpaceObjectList *nsol; - ObjectList *list; - - newobj = lalloc(sizeof(Object)); - *newobj = *obj; - newobj->type = type2; - - CFunc_SetupLocalVarInfo(newobj); - - obj->name = CParser_GetUniqueName(); - if (flag) - obj->type = CDecl_NewPointerType(type1); - else - obj->type = type1; - - CError_ASSERT(2527, (nsol = CScope_FindName(cscope_current, newobj->name)) && nsol->object == OBJ_BASE(obj)); - nsol->object = OBJ_BASE(newobj); - - list = lalloc(sizeof(ObjectList)); - list->object = newobj; - list->next = locals; - locals = list; - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - expr = create_objectnode(obj); - if (flag) { - expr->rtype = CDecl_NewPointerType(type1); - expr = makemonadicnode(expr, EINDIRECT); - } - expr->rtype = type1; - - if (type1 != type2) - expr = promote(expr, type2); - - stmt->expr = makediadicnode(create_objectnode(newobj), expr, EASS); -} - -static void CFunc_AdjustOldStyleArgs(void) { - ObjectList *list; - - for (list = arguments; list; list = list->next) { - if (IS_TYPE_FLOAT(list->object->type) && list->object->type->size < stdouble.size) - CFunc_InsertArgumentCopyConversion(list->object, TYPE(&stdouble), list->object->type, 0); - } -} - -void CFunc_SetupNewFuncArgs(Object *func, FuncArg *args) { - Object *obj; - ObjectList *newlist; - - arguments = NULL; - - if (args != &elipsis && args != &oldstyle) { - newlist = NULL; - - while (args && args != &elipsis) { - IsCompleteType(args->type); - - obj = CParser_NewLocalDataObject(NULL, 0); - obj->name = !args->name ? no_name_node : args->name; - obj->type = args->type; - obj->qual = args->qual; - obj->sclass = args->sclass; - - CFunc_SetupLocalVarInfo(obj); - - if (IS_TYPE_CLASS(obj->type) && CClass_ReferenceArgument(TYPE_CLASS(obj->type))) { - obj->type = CDecl_NewPointerType(obj->type); - TPTR_QUAL(obj->type) = Q_REFERENCE | Q_RESTRICT; - } - - if (obj->name == no_name_node && copts.ANSIstrict && !copts.cplusplus && !(func->qual & Q_MANGLE_NAME)) - CError_Error(CErrorStr127); - - if (newlist) { - newlist->next = lalloc(sizeof(ObjectList)); - newlist = newlist->next; - } else { - newlist = lalloc(sizeof(ObjectList)); - arguments = newlist; - } - - newlist->next = NULL; - newlist->object = obj; - - args = args->next; - } - } -} - -static ObjectList *CFunc_CopyObjectList(const FuncArg *args) { - Object *obj; - ObjectList *list; - ObjectList *last; - - list = NULL; - - while (args) { - if (list) { - last->next = lalloc(sizeof(ObjectList)); - last = last->next; - } else { - last = lalloc(sizeof(ObjectList)); - list = last; - } - - obj = CParser_NewLocalDataObject(NULL, 0); - obj->name = args->name; - obj->type = args->type; - obj->qual = args->qual; - obj->sclass = args->sclass; - CFunc_SetupLocalVarInfo(obj); - - last->object = obj; - last->next = NULL; - - args = args->next; - } - - return list; -} - -static void SetupFunctionArguments(Object *func, DeclInfo *di, Statement *firstStmt) { - ObjectList *list; - Object *resultobj; - Object *obj; - Type *type; - DeclInfo my_di; - - if (TYPE_FUNC(func->type)->args) { - if (di->x45) { - arguments = CFunc_CopyObjectList(di->x18); - while (1) { - if (tk == '{') - break; - - memclrw(&my_di, sizeof(my_di)); - CParser_GetDeclSpecs(&my_di, 0); - - type = my_di.thetype; - if (my_di.storageclass && my_di.storageclass != TK_REGISTER) - CError_Error(CErrorStr127); - - while (1) { - my_di.thetype = type; - my_di.name = NULL; - scandeclarator(&my_di); - if (!my_di.name) { - CError_Error(CErrorStr107); - break; - } - - adjustargumenttype(&my_di); - IsCompleteType(my_di.thetype); - - if ((obj = CFunc_IsInObjList(arguments, my_di.name))) { - if (obj->type) - CError_Error(CErrorStr333, obj); - obj->type = my_di.thetype; - obj->sclass = my_di.storageclass; - obj->qual = my_di.qual; - } else { - CError_Error(CErrorStr127); - } - - if (tk != ',') - break; - tk = lex(); - } - - if (tk != ';') - CError_ErrorSkip(CErrorStr123); - else - tk = lex(); - } - - for (list = arguments; list; list = list->next) { - if (!list->object->type) - list->object->type = TYPE(&stsignedint); - } - } else { - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - } - } - - if (CMach_GetFunctionResultClass(TYPE_FUNC(func->type)) == 1) { - resultobj = CParser_NewLocalDataObject(NULL, 0); - resultobj->name = temp_argument_name; - resultobj->type = CDecl_NewPointerType(TYPE_FUNC(func->type)->functype); - CFunc_SetupLocalVarInfo(resultobj); - - list = lalloc(sizeof(ObjectList)); - list->object = resultobj; - if (CABI_GetStructResultArgumentIndex(TYPE_FUNC(func->type))) { - CError_ASSERT(2797, arguments); - list->next = arguments->next; - arguments->next = list; - } else { - list->next = arguments; - arguments = list; - } - } - - for (list = arguments; list; list = list->next) { - NameSpaceObjectList *nsol = CScope_InsertName(cscope_current, list->object->name); - nsol->object = OBJ_BASE(list->object); - } -} - -NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func) { - NameSpace *nspace; - DeclBlock *block; - - nspace = CScope_NewListNameSpace(NULL, 0); - nspace->parent = cscope_current; - cscope_current = nspace; - - arguments = NULL; - locals = NULL; - Labels = NULL; - - localcount = 0; - cfunc_staticvarcount = 0; - - CExcept_Setup(); - - memclrw(stmt, sizeof(Statement)); - curstmt = stmt; - stmt->type = ST_NOP; - curstmtvalue = 1; - stmt->value = 1; - - blockcount = 0; - block = lalloc(sizeof(DeclBlock)); - memclrw(block, sizeof(DeclBlock)); - block->index = blockcount++; - block->parent_nspace = cscope_current; - - firstblock = block; - currentblock = block; - - return nspace; -} - -CFuncSave *CFunc_GetGlobalCompilerState(void) { - CFuncSave *state; - - if (!cscope_currentfunc && !cscope_currentclass && cscope_current == cscope_root) - return NULL; - - locklheap(); - state = lalloc(sizeof(CFuncSave)); - - CScope_SetNameSpaceScope(cscope_root, &state->scope); - - state->arguments = arguments; - arguments = NULL; - - state->locals = locals; - locals = NULL; - - state->labels = Labels; - Labels = NULL; - - state->curstmt = curstmt; - curstmt = NULL; - - state->firstblock = firstblock; - firstblock = NULL; - - state->currentblock = currentblock; - currentblock = NULL; - - state->cexcept_dobjstack = cexcept_dobjstack; - cexcept_dobjstack = NULL; - - state->sinit_label = sinit_label; - sinit_label = NULL; - - state->ainit_expr = ainit_expr; - ainit_expr = NULL; - - state->ctor_chain = ctor_chain; - ctor_chain = NULL; - - state->cinit_tempnodefunc = cinit_tempnodefunc; - cinit_tempnodefunc = NULL; - - state->trychain = trychain; - trychain = NULL; - - state->cparser_fileoffset = cparser_fileoffset; - state->symdecltoken = symdecltoken; - - state->functionbodyoffset = functionbodyoffset; - functionbodyoffset = 0; - - state->functionbodypath = functionbodypath; - functionbodypath = NULL; - - state->symdecloffset = symdecloffset; - symdecloffset = 0; - - state->symdeclend = symdeclend; - - state->sourceoffset = sourceoffset; - sourceoffset = 0; - - state->sourcefilepath = sourcefilepath; - sourcefilepath = NULL; - - state->curstmtvalue = curstmtvalue; - curstmtvalue = 0; - - state->name_obj_check = name_obj_check; - name_obj_check = NULL; - - state->check_arglist = check_arglist; - check_arglist = NULL; - - state->blockcount = blockcount; - blockcount = 0; - - state->localcount = localcount; - localcount = 0; - - state->tk = tk; - state->tkidentifier = tkidentifier; - - state->global_access = global_access; - - state->cexcept_hasdobjects = cexcept_hasdobjects; - cexcept_hasdobjects = 0; - - state->sinit_first_object = sinit_first_object; - sinit_first_object = NULL; - - state->ainit_only_one = ainit_only_one; - ainit_only_one = 0; - - state->cfunc_is_extern_c = cfunc_is_extern_c; - cfunc_is_extern_c = 0; - - state->temp_reference_init = temp_reference_init; - - return state; -} - -void CFunc_SetGlobalCompilerState(CFuncSave *state) { - if (state) { - CScope_RestoreScope(&state->scope); - - arguments = state->arguments; - locals = state->locals; - Labels = state->labels; - curstmt = state->curstmt; - firstblock = state->firstblock; - currentblock = state->currentblock; - cexcept_dobjstack = state->cexcept_dobjstack; - sinit_label = state->sinit_label; - ainit_expr = state->ainit_expr; - ctor_chain = state->ctor_chain; - cinit_tempnodefunc = state->cinit_tempnodefunc; - trychain = state->trychain; - name_obj_check = state->name_obj_check; - check_arglist = state->check_arglist; - curstmtvalue = state->curstmtvalue; - cparser_fileoffset = state->cparser_fileoffset; - symdecltoken = state->symdecltoken; - functionbodyoffset = state->functionbodyoffset; - functionbodypath = state->functionbodypath; - symdecloffset = state->symdecloffset; - symdeclend = state->symdeclend; - sourceoffset = state->sourceoffset; - sourcefilepath = state->sourcefilepath; - blockcount = state->blockcount; - tk = state->tk; - tkidentifier = state->tkidentifier; - global_access = state->global_access; - localcount = state->localcount; - cexcept_hasdobjects = state->cexcept_hasdobjects; - sinit_first_object = state->sinit_first_object; - ainit_only_one = state->ainit_only_one; - cfunc_is_extern_c = state->cfunc_is_extern_c; - temp_reference_init = state->temp_reference_init; - - unlocklheap(); - } -} - -void CFunc_Gen(Statement *stmt, Object *func, UInt8 unk) { - Boolean flag; - CI_FuncData packed; - - if ((TYPE_FUNC(func->type)->flags & FUNC_FLAGS_400000) && !anyerrors) { - CInline_PackIFunctionData(&packed, stmt, func); - flag = 1; - } else { - flag = 0; - } - - CInline_GenFunc(stmt, func, unk); - - if (flag) - CClass_DefineCovariantFuncs(func, &packed); -} - -static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) { - ObjMemberVar *ivar; - CtorChain *scan; - - if (tclass->mode != CLASS_MODE_UNION) { - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - if (IS_TYPE_REFERENCE(ivar->type)) { - for (scan = chain; scan; scan = scan->next) { - if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar) - break; - } - - if (!scan) - CError_Error(CErrorStr256, ivar->name->name); - } else if (CParser_IsConst(ivar->type, ivar->qual)) { - for (scan = chain; scan; scan = scan->next) { - if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar) - break; - } - - if (!scan && !IS_TYPE_CLASS(ivar->type)) - CError_Error(CErrorStr255, ivar->name->name); - } - } - } -} - -void CFunc_CheckClassCtors(TypeClass *tclass) { - CFunc_CheckCtorInitializer(tclass, NULL); -} - -static void CFunc_ParseCtorInitializer(void) { - CtorChain *chain; - ENodeList *args; - TypeClass *tclass; - ObjMemberVar *ivar; - ClassList *base; - VClassList *vbase; - ENode *expr; - Type *origtype; - - ctor_chain = NULL; - - if (tk == ':') { - do { - tclass = NULL; - switch ((tk = lex())) { - case TK_IDENTIFIER: - for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) { - if (ivar->name == tkidentifier && lookahead() == '(') - goto do_ivar; - } - for (base = cscope_currentclass->bases; base; base = base->next) { - if (base->base->classname == tkidentifier) { - if (lookahead() == '(') { - tclass = base->base; - tk = lex(); - } else { - tkidentifier = base->base->classname; - } - break; - } - } - break; - - case TK_COLON_COLON: - break; - - default: - CError_Error(CErrorStr212); - return; - } - - if (!tclass) - tclass = CClass_GetQualifiedClass(); - - if (tclass) { - for (vbase = cscope_currentclass->vbases; vbase; vbase = vbase->next) { - if (vbase->base == tclass) - break; - } - - if (vbase) { - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_VBase && chain->u.vbase == vbase) { - CError_Error(CErrorStr212); - return; - } - } - - chain = lalloc(sizeof(CtorChain)); - chain->what = CtorChain_VBase; - chain->u.vbase = vbase; - } else { - for (base = cscope_currentclass->bases; base; base = base->next) { - if (base->base == tclass) - break; - } - - if (base) { - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_Base && chain->u.base == base) { - CError_Error(CErrorStr212); - return; - } - } - - chain = lalloc(sizeof(CtorChain)); - chain->what = CtorChain_Base; - chain->u.base = base; - } else { - CError_Error(CErrorStr212); - return; - } - } - } else { - for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) { - if (ivar->name == tkidentifier) - break; - } - - if (ivar) { - do_ivar: - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar) - CError_Error(CErrorStr212); - } - - chain = lalloc(sizeof(CtorChain)); - chain->what = CtorChain_MemberVar; - chain->u.membervar = ivar; - } else { - CError_Error(CErrorStr212); - return; - } - - tk = lex(); - } - - if (tk != '(') { - CError_Error(CErrorStr114); - return; - } - - tk = lex(); - args = CExpr_ScanExpressionList(1); - - if (tk != ')') { - CError_Error(CErrorStr115); - return; - } - - switch (chain->what) { - case CtorChain_Base: - expr = CABI_MakeThisExpr(NULL, chain->u.base->offset); - chain->objexpr = CExpr_ConstructObject(chain->u.base->base, expr, args, 1, 0, 0, 0, 1); - break; - case CtorChain_VBase: - expr = CABI_MakeThisExpr(chain->u.vbase->base, chain->u.vbase->offset); - chain->objexpr = CExpr_ConstructObject(chain->u.vbase->base, expr, args, 1, 0, 0, 0, 1); - break; - case CtorChain_MemberVar: - expr = CABI_MakeThisExpr(cscope_currentclass, chain->u.membervar->offset); - expr->flags = chain->u.membervar->qual & ENODE_FLAG_QUALS; - switch (chain->u.membervar->type->type) { - case TYPECLASS: - chain->objexpr = CExpr_ConstructObject(TYPE_CLASS(chain->u.membervar->type), expr, args, 1, 1, 0, 1, 1); - break; - case TYPEARRAY: - if (args) { - CError_Error(CErrorStr212); - continue; - } - chain->objexpr = NULL; - break; - default: - if (!args) { - args = lalloc(sizeof(ENodeList)); - args->next = NULL; - args->node = CExpr_DoExplicitConversion(chain->u.membervar->type, chain->u.membervar->qual, NULL); - } - if (args->next) { - CError_Error(CErrorStr212); - return; - } - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = chain->u.membervar->type; - if (IS_TYPE_BITFIELD(origtype = expr->rtype)) { - expr->data.monadic = makemonadicnode(expr->data.monadic, EBITFIELD); - expr->data.monadic->rtype = origtype; - expr->rtype = TYPE_BITFIELD(origtype)->bitfieldtype; - } - - chain->objexpr = makediadicnode(expr, CExpr_AssignmentPromotion(args->node, expr->rtype, expr->flags, 1), EASS); - } - break; - default: - CError_FATAL(3286); - } - - chain->next = ctor_chain; - ctor_chain = chain; - } while ((tk = lex()) == ','); - } -} - -static void CFunc_FunctionRedefinedCheck(Object *func) { - if (TYPE_FUNC(func->type)->flags & FUNC_AUTO_GENERATED) - CError_Error(CErrorStr333, func); - - if ((TYPE_FUNC(func->type)->flags & FUNC_DEFINED) && func->datatype != DINLINEFUNC) - CError_Error(CErrorStr333, func); - - TYPE_FUNC(func->type)->flags |= FUNC_DEFINED; -} - -static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) { - Object *obj; - Object *aliasobj; - DeclInfo di; - - memclrw(&di, sizeof(di)); - di.name = name; - di.storageclass = TK_STATIC; - di.qual = Q_CONST; - di.thetype = CDecl_NewArrayType(TYPE(&stchar), strlen(str) + 1); - - obj = CParser_NewGlobalDataObject(&di); - aliasobj = CParser_NewAliasObject(obj, 0); - obj->nspace = cscope_root; - obj->datatype = DDATA; - CFunc_NameLocalStaticDataObject(obj, obj->name->name); - - return aliasobj; -} - -void CFunc_ParseFuncDef(Object *func, DeclInfo *di, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) { - Boolean has_try; - Object *nameobj_func; - Object *nameobj_FUNCTION; - Object *nameobj_pretty; - char *prettyname; - Statement *stmt18; - Statement *stmt16; - Statement firstStmt; - DeclThing thing; - CScopeSave scope; - - nameobj_func = NULL; - nameobj_FUNCTION = NULL; - nameobj_pretty = NULL; - prettyname = NULL; - - CError_ASSERT(3373, IS_TYPE_FUNC(func->type)); - - CFunc_FunctionRedefinedCheck(func); - CParser_UpdateObject(func, di); - - if (!is_method) { - CScope_SetFunctionScope(func, &scope); - if (tclass) - cscope_current = tclass->nspace; - } else { - CScope_SetMethodScope(func, tclass, is_static, &scope); - } - - if (nspace) - cscope_current = nspace; - - if (cscope_currentclass) - CClass_MemberDef(func, cscope_currentclass); - - cfunc_is_extern_c = di->is_extern_c; - - CError_ASSERT(3392, IS_TYPE_FUNC(func->type)); - if (di->x45 && (func->qual & Q_ASM)) - CError_Error(CErrorStr176); - - if (cparamblkptr->precompile == 1 && !(func->qual & Q_INLINE)) - CError_ErrorTerm(CErrorStr180); - - if (di->x49) - CError_Error(CErrorStr127); - - CFunc_FuncGenSetup(&firstStmt, func); - if (!IS_TYPE_VOID(TYPE_FUNC(func->type)->functype)) - IsCompleteType(TYPE_FUNC(func->type)->functype); - - SetupFunctionArguments(func, di, &firstStmt); - - stmt18 = curstmt; - CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); - functionbodyoffset = sourceoffset; - firstStmt.sourceoffset = sourceoffset; - functionbodypath = sourcefilepath; - firstStmt.sourcefilepath = sourcefilepath; - - if (di->x45) - CFunc_AdjustOldStyleArgs(); - - if (di->x1C) - CScope_MergeNameSpace(cscope_current, di->x1C); - - if (tk == TK_TRY) { - tk = lex(); - has_try = 1; - } else { - has_try = 0; - } - - if (CClass_IsConstructor(func)) { - CError_ASSERT(3445, cscope_currentclass); - CFunc_ParseCtorInitializer(); - CFunc_CheckCtorInitializer(cscope_currentclass, ctor_chain); - } - - CPrep_TokenStreamFlush(); - - if (!(func->qual & Q_ASM)) { - if (tk == '{') { - if (!has_try) - tk = lex(); - } else { - CError_ErrorSkip(CErrorStr135); - has_try = 0; - } - - if (func->name) { - nameobj_func = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__func__")); - nameobj_FUNCTION = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__FUNCTION__")); - prettyname = CError_GetObjectName(func); - nameobj_pretty = CFunc_DeclareFuncName(prettyname, GetHashNameNode("__PRETTY_FUNCTION__")); - } - - if (!copts.cplusplus) - CFunc_ParseLocalDeclarationList(0, 0, 0, 0); - - thing.switchinfo = NULL; - thing.loopContinue = NULL; - thing.loopBreak = NULL; - thing.thetype = TYPE_FUNC(func->type)->functype; - thing.qual = TYPE_FUNC(func->type)->qual; - - if (has_try) { - CExcept_ScanTryBlock(&thing, CClass_IsConstructor(func) || CClass_IsDestructor(func)); - if (tk != 0) - CPrep_UnLex(); - tk = '}'; - } else { - while (tk != '}') - statement(&thing); - } - - stmt16 = curstmt; - - if (stmt16->type != ST_RETURN && stmt16->type != ST_GOTO) { - CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); - CFunc_AppendStatement(ST_RETURN); - - curstmt->dobjstack = NULL; - curstmt->expr = NULL; - - if ( - (copts.cplusplus || copts.c9x) && - !strcmp(func->name->name, "main") && - TYPE_FUNC(func->type)->functype == TYPE(&stsignedint) - ) - curstmt->expr = intconstnode(TYPE(&stsignedint), 0); - - if ( - stmt16->type == ST_EXPRESSION && - stmt16->expr->type == EFUNCCALL && - stmt16->expr->rtype == &stvoid && - (stmt16->expr->flags & ENODE_FLAG_VOLATILE) - ) - curstmt->flags = curstmt->flags | StmtFlag_8; - } - - CheckCLabels(); - - if (nameobj_func && (nameobj_func->flags & OBJECT_USED)) - CInit_DeclareData(nameobj_func->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1); - if (nameobj_FUNCTION && (nameobj_FUNCTION->flags & OBJECT_USED)) - CInit_DeclareData(nameobj_FUNCTION->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1); - if (nameobj_pretty && (nameobj_pretty->flags & OBJECT_USED)) - CInit_DeclareData(nameobj_pretty->u.alias.object, prettyname, NULL, strlen(prettyname) + 1); - - if (!fatalerrors) { - if (CClass_IsConstructor(func)) - CABI_TransConstructor(func, stmt18, cscope_currentclass, NULL, has_try); - if (CClass_IsDestructor(func)) - CABI_TransDestructor(func, func, &firstStmt, cscope_currentclass, 0); - - CFunc_DestructorCleanup(&firstStmt); - CFunc_CodeCleanup(&firstStmt); - symdeclend = CPrep_GetFileOffsetInfo(&cparser_fileoffset); - CFunc_Gen(&firstStmt, func, di->x45); - } - } else { - if (tk == '{') { - in_assembler = 1; - tk = lex(); - in_assembler = 0; - } else { - CError_ErrorSkip(CErrorStr135); - } - - CFunc_ParseLocalDeclarationList(1, 0, 0, 0); - Assembler(func); - } - - if (tk != '}') - CError_Error(CErrorStr130); - - CScope_RestoreScope(&scope); -} - -void InitExpr_Register(ENode *expr, Object *object) { - InitExpr *initexpr; - InitExpr *scan; - - if ( - cparamblkptr->precompile == 1 && - object->sclass != TK_STATIC && - !(object->qual & (Q_20000 | Q_WEAK)) - ) - { - CError_Error(CErrorStr180); - return; - } - - if (copts.suppress_init_code) - return; - - initexpr = galloc(sizeof(InitExpr)); - initexpr->next = NULL; - initexpr->object = object; - initexpr->expr = CInline_CopyExpression(expr, CopyMode1); - - if (init_expressions) { - scan = init_expressions; - while (scan->next) - scan = scan->next; - scan->next = initexpr; - } else { - init_expressions = initexpr; - } -} - -void CFunc_GenerateDummyFunction(Object *func) { - NameSpace *nspace; - Boolean saveDebugInfo; - Statement firstStmt; - - if (!anyerrors) { - nspace = CFunc_FuncGenSetup(&firstStmt, NULL); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_CodeCleanup(&firstStmt); - CFunc_Gen(&firstStmt, func, 0); - - cscope_current = nspace->parent; - copts.filesyminfo = saveDebugInfo; - } -} - -void CFunc_GenerateSingleExprFunc(Object *func, ENode *expr) { - NameSpace *nspace; - Boolean saveDebugInfo; - Statement firstStmt; - Statement *stmt; - - if (cparamblkptr->precompile == 1) { - CError_Error(CErrorStr180); - return; - } - - if (!anyerrors) { - nspace = CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; - - CFunc_CodeCleanup(&firstStmt); - CInline_GenFunc(&firstStmt, func, 0); - - cscope_current = nspace->parent; - copts.filesyminfo = saveDebugInfo; - } -} - -void CFunc_GenerateDummyCtorFunc(Object *func, Object *real_ctor) { - ENode *expr; - NameSpace *nspace; - FuncArg *arg1; - FuncArg *arg0; - ENodeList *list; - Boolean saveDebugInfo; - Statement firstStmt; - Statement *stmt; - - if (cparamblkptr->precompile == 1) { - CError_Error(CErrorStr180); - return; - } - - if (!anyerrors) { - cscope_currentfunc = func; - - nspace = CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - expr = CExpr_NewENode(EFUNCCALL); - expr->type = EFUNCCALL; - expr->cost = 200; - expr->rtype = TYPE(&void_ptr); - expr->data.funccall.funcref = CExpr_MakeObjRefNode(real_ctor, 0); - expr->data.funccall.functype = TYPE_FUNC(func->type); - - CError_ASSERT(3716, IS_TYPE_FUNC(real_ctor->type)); - CError_ASSERT(3717, TYPE_FUNC(real_ctor->type)->flags & FUNC_METHOD); - CError_ASSERT(3718, arg0 = TYPE_FUNC(real_ctor->type)->args); - CError_ASSERT(3720, arg1 = arg0->next); - CError_ASSERT(3721, arguments); - - list = lalloc(sizeof(ENodeList)); - expr->data.funccall.args = list; - list->node = create_objectnode(arguments->object); - - if (TYPE_METHOD(real_ctor->type)->theclass->flags & CLASS_HAS_VBASES) { - CError_ASSERT(3727, arg1 = arg1->next); - CError_ASSERT(3728, arguments->next); - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = create_objectnode(arguments->next->object); - } - - while (arg1) { - CError_ASSERT(3737, arg1->dexpr); - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = CExpr_GetDefaultArgument(expr->data.funccall.funcref, arg1); - arg1 = arg1->next; - } - - list->next = NULL; - - stmt = CFunc_AppendStatement(ST_RETURN); - stmt->expr = expr; - - CFunc_CodeCleanup(&firstStmt); - CInline_GenFunc(&firstStmt, func, 0); - - cscope_current = nspace->parent; - cscope_currentfunc = NULL; - copts.filesyminfo = saveDebugInfo; - } -} |