diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CInit.c')
-rw-r--r-- | compiler_and_linker/unsorted/CInit.c | 3082 |
1 files changed, 0 insertions, 3082 deletions
diff --git a/compiler_and_linker/unsorted/CInit.c b/compiler_and_linker/unsorted/CInit.c deleted file mode 100644 index c2d2299..0000000 --- a/compiler_and_linker/unsorted/CInit.c +++ /dev/null @@ -1,3082 +0,0 @@ -#include "compiler/CInit.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/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CParser.h" -#include "compiler/CPrec.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CScope.h" -#include "compiler/CompilerTools.h" -#include "compiler/ObjGenMachO.h" -#include "compiler/objects.h" -#include "compiler/types.h" - -TempNodeCB cinit_tempnodefunc; -InitInfo *cinit_initinfo; -static PooledString *cinit_stringlist; -static PooledString *cinit_pooledstringlist; -static PooledString *cinit_pooledwstringlist; -static ObjectList *cinit_tentative; -static TypeClass *cinit_loop_class; -static ENodeList *cinit_fdtnode; -static Boolean cinit_fdtambig; - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct CInit_1C { - struct CInit_1C *next; - Type *type; - ENode *expr; - SInt32 offset; -} CInit_1C; - -typedef struct CInit_Stuff { - struct CInit_Stuff *x0; - struct CInit_Stuff *x4; - char *buffer; - SInt32 xC; - SInt32 size; - SInt32 bufferSize; - SInt32 x18; - CInit_1C *x1C; - OLinkList *list; - Boolean flag; -} CInit_Stuff; - -typedef enum { - Stage0, - Stage1, - Stage2, - Stage3, - Stage4 -} Stage; - -typedef struct CInit_Stuff2 { - ENode *expr; - ENode myexpr; - Stage stage; - Boolean x23; - SInt32 x24; - Type *type; -} CInit_Stuff2; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -// forward decls -static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32 qual, Boolean flag); -static void CInit_Type(Type *type, UInt32 qual, Boolean flag); - -void CInit_Init(void) { - cinit_tempnodefunc = NULL; - cinit_initinfo = NULL; - cinit_stringlist = NULL; - cinit_pooledstringlist = NULL; - cinit_pooledwstringlist = NULL; - cinit_tentative = NULL; -} - -static void CInit_SetupInitInfo(InitInfo *info, Object *obj) { - memclrw(info, sizeof(InitInfo)); - info->obj = obj; - info->next = cinit_initinfo; - cinit_initinfo = info; -} - -static void CInit_CleanupInitInfo(InitInfo *info) { - cinit_initinfo = info->next; -} - -static void CInit_SetupInitInfoBuffer(Type *type) { - SInt32 size = type->size; - cinit_initinfo->size = size; - - if (!size) - size = 512; - else if (size & 1) - size++; - - cinit_initinfo->buffer = lalloc(size); - cinit_initinfo->bufferSize = size; - memclrw(cinit_initinfo->buffer, size); -} - -static void CInit_SetData(void *data, SInt32 offset, SInt32 size) { - SInt32 end; - char *buffer; - - end = offset + size; - if (end > cinit_initinfo->size) - cinit_initinfo->size = end; - - if (end > cinit_initinfo->bufferSize) { - if (cinit_initinfo->obj->type->size == 0) { - if (end < 8000) - end += 0x400; - else - end += 0x4000; - } - if (end & 1) - end++; - - buffer = lalloc(end); - memclrw(buffer, end); - memcpy(buffer, cinit_initinfo->buffer, cinit_initinfo->bufferSize); - cinit_initinfo->buffer = buffer; - cinit_initinfo->bufferSize = end; - } - - if (data) - memcpy(cinit_initinfo->buffer + offset, data, size); -} - -typedef struct CInit_Initializer { - struct CInit_Initializer *next; - struct CInit_Initializer *sublist; - ENode *expr; - TStreamElement element; -} CInit_Initializer; - -static CInit_Initializer *CInit_ParseInitializerList(void) { - CInit_Initializer *r30; - CInit_Initializer *r29; - CInit_Initializer *tmp; - - if ((tk = lex()) == '}') - return NULL; - - r30 = NULL; - do { - if (r30) { - tmp = lalloc(sizeof(CInit_Initializer)); - r29->next = tmp; - r29 = tmp; - } - if (!r30) { - r30 = r29 = lalloc(sizeof(CInit_Initializer)); - } - r29->next = NULL; - - if (tk == '{') { - r29->element = *CPrep_CurStreamElement(); - r29->sublist = CInit_ParseInitializerList(); - r29->expr = NULL; - tk = lex(); - } else { - r29->sublist = NULL; - r29->expr = conv_assignment_expression(); - r29->element = *CPrep_CurStreamElement(); - } - - if (tk == '}') - return r30; - - if (tk != ',') { - CError_Error(CErrorStr116); - return r30; - } - } while ((tk = lex()) != '}'); - - return r30; -} - -static CInit_Initializer *CInit_ParseInitializerClause(void) { - CInit_Initializer *init; - - init = lalloc(sizeof(CInit_Initializer)); - init->next = NULL; - if (tk != '{') { - init->sublist = NULL; - init->expr = conv_assignment_expression(); - init->element = *CPrep_CurStreamElement(); - } else { - init->element = *CPrep_CurStreamElement(); - init->expr = NULL; - init->sublist = CInit_ParseInitializerList(); - tk = lex(); - } - - return init; -} - -static ENode *CInit_ParseInitializer(ENode *expr) { - CInt64 save_int; - Float save_float; - SInt32 save_size; - short t; - - switch (tk) { - case TK_INTCONST: - case TK_FLOATCONST: - save_int = tkintconst; - save_float = tkfloatconst; - save_size = tksize; - t = lookahead(); - tkintconst = save_int; - tkfloatconst = save_float; - tksize = save_size; - - switch (t) { - case ',': - case ';': - case '}': - memclrw(expr, sizeof(ENode)); - switch (tk) { - case TK_INTCONST: - expr->type = EINTCONST; - expr->rtype = atomtype(); - expr->data.intval = tkintconst; - break; - case TK_FLOATCONST: - expr->type = EFLOATCONST; - expr->rtype = atomtype(); - expr->data.floatval = tkfloatconst; - break; - } - tk = lex(); - CPrep_TokenStreamFlush(); - return expr; - } - } - - expr = assignment_expression(); - CPrep_TokenStreamFlush(); - return expr; -} - -static Stage CInit_ParseNextInit(CInit_Stuff2 *s) { - DeclInfo di; - short t; - - s->expr = NULL; - if (tk == ';') { - s->stage = Stage4; - return Stage4; - } - switch (s->stage) { - case Stage0: - if (s->x23) { - if (tk == '(') { - tk = lex(); - CParser_GetDeclSpecs(&di, 1); - s->type = di.thetype; - if (tk == ')') - tk = lex(); - else - CError_Error(CErrorStr115); - - if (tk == '(') - tk = lex(); - else - CError_Error(CErrorStr114); - s->x24++; - t = lookahead(); - if (t == TK_UU_VECTOR || (t == TK_IDENTIFIER && !strcmp("vector", tkidentifier->name))) - CInit_ParseNextInit(s); - s->stage = Stage1; - return Stage1; - } - } else { - if (tk == '{') { - tk = lex(); - s->x24 = 0; - s->stage = Stage1; - return Stage1; - } - } - s->expr = CInit_ParseInitializer(&s->myexpr); - s->stage = Stage2; - return Stage2; - case Stage1: - break; - case Stage2: - case Stage3: - if (tk == ',') { - tk = lex(); - break; - } - if (s->x24) { - if (tk != ')') - CError_Error(CErrorStr174); - if (s->x24 > 1) { - s->x24--; - tk = lex(); - CInit_ParseNextInit(s); - } - } else { - if (tk != '}') - CError_Error(CErrorStr174); - } - s->stage = Stage3; - return Stage3; - default: - CError_FATAL(389); - } - - switch (tk) { - case '{': - tk = lex(); - s->stage = Stage1; - return Stage1; - case '}': - s->stage = Stage3; - return Stage3; - case '(': - if (s->x23) { - tk = lex(); - s->stage = Stage1; - return Stage1; - } - case ')': - if (s->x23 && s->x24) { - if (s->x24 > 1) { - s->x24--; - tk = lex(); - CInit_ParseNextInit(s); - } - s->stage = Stage3; - return Stage3; - } - default: - s->expr = CInit_ParseInitializer(&s->myexpr); - s->stage = Stage2; - return Stage2; - } -} - -static void CInit_CloseInitList(void) { - if (tk == ',' && copts.cplusplus) - tk = lex(); - - if (tk != '}') - CError_ErrorSkip(CErrorStr130); - else - tk = lex(); -} - -static Boolean CInit_IsAllZero(char *buf, SInt32 size) { - SInt32 i; - - if (copts.explicit_zero_data) - return 0; - - for (i = 0; i < size; i++) - if (buf[i]) return 0; - - return 1; -} - -static Boolean CInit_ClassNeedsConstruction(TypeClass *tclass) { - return CClass_Constructor(tclass) || CClass_Destructor(tclass); -} - -static Boolean CInit_IsSimpleStructArrayInit(Type *type) { - switch (type->type) { - case TYPESTRUCT: - return 1; - case TYPEARRAY: - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (!IS_TYPE_CLASS(type)) - return 1; - case TYPECLASS: - return !CInit_ClassNeedsConstruction(TYPE_CLASS(type)); - default: - return 0; - } -} - -static Boolean CInit_IsSimpleInit(Type *type) { - switch (type->type) { - case TYPEPOINTER: - return (TYPE_POINTER(type)->qual & Q_REFERENCE) == 0; - case TYPEARRAY: - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (!IS_TYPE_CLASS(type)) - return 1; - case TYPECLASS: - return !CInit_ClassNeedsConstruction(TYPE_CLASS(type)); - default: - return 1; - } -} - -static Object *CInit_GetInitObject(Object *obj) { - if (obj->datatype == DALIAS) { - CError_ASSERT(521, !obj->u.alias.offset); - obj = obj->u.alias.object; - } - return obj; -} - -static Object *CInit_CreateStaticDataObject(Type *type, UInt32 qual, HashNameNode *name) { - Object *obj; - DeclInfo di; - - memclrw(&di, sizeof(DeclInfo)); - di.thetype = type; - di.name = name ? name : CParser_GetUniqueName(); - di.qual = qual; - di.storageclass = TK_STATIC; - di.is_extern_c = 1; - - obj = CParser_NewGlobalDataObject(&di); - obj->nspace = cscope_root; - return obj; -} - -static Type *CInit_GetRegMemType(void) { - return CDecl_NewStructType(void_ptr.size * 3, CMach_GetTypeAlign((Type *) &void_ptr)); -} - -static Object *CInit_CreateStaticData(Type *type) { - Object *obj = CInit_CreateStaticDataObject(type, 0, NULL); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - return obj; -} - -static void CInit_InitNonConst(CInit_Stuff *s, Type *type, ENode *expr) { - CInit_1C *entry; - CInit_1C *scan; - MWVector128 *vec; - - if (s->x4->flag || IS_TYPE_VECTOR(type)) { - if (IS_TYPE_VECTOR(type) && ENODE_IS(expr, EVECTOR128CONST)) { - vec = (MWVector128 *) (s->buffer + s->size); - *vec = expr->data.vector128val; - CMach_InitVectorMem(type, *vec, vec, 1); - } - - entry = lalloc(sizeof(CInit_1C)); - memclrw(entry, sizeof(CInit_1C)); - entry->next = NULL; - entry->type = type; - entry->expr = expr; - entry->offset = s->xC + s->size; - if ((scan = s->x4->x1C)) { - while (scan->next) - scan = scan->next; - scan->next = entry; - } else { - s->x4->x1C = entry; - } - } else { - CError_Error(CErrorStr124); - } -} - -static CInit_Stuff *CInit_GrowBuffer(CInit_Stuff *s, SInt32 size) { - CInit_Stuff *newbuf; - - newbuf = lalloc(sizeof(CInit_Stuff)); - memclrw(newbuf, sizeof(CInit_Stuff)); - newbuf->x4 = s->x4; - newbuf->buffer = lalloc(size); - newbuf->xC = s->xC + s->size; - newbuf->bufferSize = size; - s->x0 = newbuf; - memset(newbuf->buffer, 0, newbuf->bufferSize); - return newbuf; -} - -Boolean CInit_RelocInitCheck(ENode *expr, Object **objptr, CInt64 *valptr, Boolean flag) { - Object *objcheck1; - Object *objcheck2; - CInt64 valcheck1; - CInt64 valcheck2; - - *objptr = NULL; - valptr->lo = 0; - valptr->hi = 0; - - while (1) { - switch (expr->type) { - case EINTCONST: - *valptr = expr->data.intval; - return 1; - case EOBJREF: - objcheck1 = CInit_GetInitObject(expr->data.objref); - if (objcheck1->datatype == DLOCAL && !flag) - return 0; - *objptr = objcheck1; - return 1; - case ESTRINGCONST: - CInit_RewriteString(expr, 0); - continue; - case ETYPCON: - do { - if (expr->rtype->size != expr->data.monadic->rtype->size) - return 0; - expr = expr->data.monadic; - if (!IS_TYPE_POINTER_ONLY(expr->rtype) && !IS_TYPE_INT(expr->rtype)) - return 0; - } while (ENODE_IS(expr, ETYPCON)); - continue; - case EADD: - if (!CInit_RelocInitCheck(expr->data.diadic.left, &objcheck1, &valcheck1, flag)) - return 0; - if (!CInit_RelocInitCheck(expr->data.diadic.right, &objcheck2, &valcheck2, flag)) - return 0; - - if (objcheck1) { - if (objcheck2) - return 0; - *objptr = objcheck1; - } else { - *objptr = objcheck1; - } - - *valptr = CMach_CalcIntDiadic(TYPE(&stunsignedlong), valcheck1, '+', valcheck2); - return 1; - case ESUB: - if (!CInit_RelocInitCheck(expr->data.diadic.left, &objcheck1, &valcheck1, flag)) - return 0; - if (!CInit_RelocInitCheck(expr->data.diadic.right, &objcheck2, &valcheck2, flag)) - return 0; - - if (objcheck2) - return 0; - - *objptr = objcheck1; - *valptr = CMach_CalcIntDiadic(TYPE(&stunsignedlong), valcheck1, '-', valcheck2); - return 1; - default: - return 0; - } - } -} - -static void CInit_InitTypePointer(CInit_Stuff *s, ENode *expr, TypePointer *tptr, UInt32 qual) { - Object *obj; - CInt64 val; - OLinkList *list; - - expr = CExpr_AssignmentPromotion(expr, TYPE(tptr), qual & (Q_CONST | Q_VOLATILE), 1); - if (IS_TYPE_POINTER_ONLY(expr->rtype) || ENODE_IS(expr, EINTCONST)) { - if (CInit_RelocInitCheck(expr, &obj, &val, 0)) { - if (obj) { - list = lalloc(sizeof(OLinkList)); - list->next = s->x4->list; - list->obj = obj; - list->somevalue = CInt64_GetULong(&val); - list->offset = s->xC + s->size; - s->x4->list = list; - } else { - CMach_InitIntMem(TYPE(&stunsignedlong), val, s->buffer + s->size); - } - } else { - CInit_InitNonConst(s, TYPE(tptr), expr); - } - } else { - CError_Error(CErrorStr174); - } -} - -static void CInit_InitTypeInt(CInit_Stuff *s, ENode *expr, TypeIntegral *tint, UInt32 qual) { - expr = CExpr_AssignmentPromotion(expr, TYPE(tint), qual & (Q_CONST | Q_VOLATILE), 1); - if (IS_TYPE_INT(expr->rtype)) { - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(TYPE(tint), expr->data.intval, s->buffer + s->size); - } else if (ENODE_IS(expr, ETYPCON) && IS_TYPE_POINTER_ONLY(expr->data.monadic->rtype) && expr->rtype->size == 4 && (copts.cplusplus || !copts.ANSIstrict)) { - CInit_InitTypePointer(s, expr->data.monadic, TYPE_POINTER(expr->data.monadic->rtype), qual); - } else { - CInit_InitNonConst(s, TYPE(tint), expr); - } - } else { - CError_Error(CErrorStr174); - } -} - -static void CInit_InitTypeFloat(CInit_Stuff *s, ENode *expr, TypeIntegral *tint, UInt32 qual) { - expr = CExpr_AssignmentPromotion(expr, TYPE(tint), qual & (Q_CONST | Q_VOLATILE), 1); - if (IS_TYPE_FLOAT(expr->rtype)) { - if (ENODE_IS(expr, EFLOATCONST)) { - CMach_InitFloatMem(TYPE(tint), expr->data.floatval, s->buffer + s->size); - } else { - CInit_InitNonConst(s, TYPE(tint), expr); - } - } else { - CError_Error(CErrorStr174); - } -} - -static void CInit_InitTypeEnum(CInit_Stuff *s, ENode *expr, TypeEnum *tenum, UInt32 qual) { - expr = CExpr_AssignmentPromotion(expr, TYPE(tenum), qual & (Q_CONST | Q_VOLATILE), 1); - if (IS_TYPE_ENUM(expr->rtype)) { - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(tenum->enumtype, expr->data.intval, s->buffer + s->size); - } else { - CInit_InitNonConst(s, TYPE(tenum), expr); - } - } else { - CError_Error(CErrorStr174); - } -} - -static void CInit_InitTypeMemberPointer(CInit_Stuff *s, ENode *expr, TypeMemberPointer *tmptr, UInt32 qual) { - expr = CExpr_AssignmentPromotion(expr, TYPE(tmptr), qual & (Q_CONST | Q_VOLATILE), 1); - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(TYPE(&stsignedlong), expr->data.intval, s->buffer + s->size); - } else { - CInit_InitNonConst(s, TYPE(tmptr), expr); - } -} - -static void CInit_SetBitfield(TypeBitfield *tbitfield, UInt8 *buffer, CInt64 val) { - int i; - int pos; - int step; - - if (copts.littleendian) { - pos = tbitfield->offset; - step = 1; - } else { - pos = tbitfield->bitlength + tbitfield->offset - 1; - step = -1; - } - for (i = 0; i < tbitfield->bitlength; i++, pos += step) { - if (CInt64_GetULong(&val) & 1) { - if (copts.littleendian) { - buffer[pos >> 3] |= 1 << (pos & 7); - } else { - buffer[pos >> 3] |= 0x80 >> (pos & 7); - } - } - val = CInt64_ShrU(val, cint64_one); - } -} - -static void CInit_InitTypeBitfield(CInit_Stuff *s, ENode *expr, TypeBitfield *tbitfield, UInt32 qual) { - Type *inner; - - inner = tbitfield->bitfieldtype; - if (IS_TYPE_ENUM(inner)) - inner = TYPE_ENUM(inner)->enumtype; - expr = CExpr_AssignmentPromotion(expr, inner, qual & (Q_CONST | Q_VOLATILE), 1); - - if (IS_TYPE_INT(expr->rtype)) { - if (ENODE_IS(expr, EINTCONST)) { - CInit_SetBitfield(tbitfield, (UInt8 *) s->buffer + s->size, expr->data.intval); - } else { - CInit_InitNonConst(s, TYPE(tbitfield), expr); - } - } else { - CError_Error(CErrorStr174); - } -} - -static void CInit_InitTypeArray(CInit_Stuff *s, CInit_Stuff2 *s2, TypePointer *tptr, UInt32 qual, Boolean errorflag) { - SInt32 targetsize; - SInt32 start; - SInt32 i; - Boolean flag; - Boolean is_zero_size; - SInt32 size; - SInt32 tmp; - Boolean is_char_ptr; - Boolean is_wchar_ptr; - - is_zero_size = tptr->size == 0; - targetsize = tptr->target->size; - if (!targetsize) { - CError_Error(CErrorStr145); - return; - } - - is_char_ptr = IS_TYPE_INT(tptr->target) && (targetsize == 1); - is_wchar_ptr = IS_TYPE_INT(tptr->target) && (targetsize == stwchar.size); - switch (s2->stage) { - case Stage1: - flag = 1; - if (CInit_ParseNextInit(s2) == Stage3) { - if (is_zero_size) - CError_Error(CErrorStr174); - tk = lex(); - return; - } - break; - case Stage2: - flag = 0; - break; - } - switch (s2->stage) { - case Stage1: - case Stage2: - break; - default: - CError_Error(CErrorStr174); - return; - } - - if (s2->stage == Stage2) - s2->expr = pointer_generation(s2->expr); - - if (s2->stage == Stage2 && ENODE_IS(s2->expr, ESTRINGCONST) && (is_char_ptr || is_wchar_ptr)) { - if (IS_TYPE_POINTER_ONLY(s2->expr->rtype) && tptr->target->size != TYPE_POINTER(s2->expr->rtype)->target->size) - CError_Warning(CErrorStr174); - size = tmp = s2->expr->data.string.size; - if (is_zero_size) { - tptr->size = s2->expr->data.string.size; - if (s->bufferSize < tmp) - s = CInit_GrowBuffer(s, tmp); - memcpy(s->buffer, s2->expr->data.string.data, size); - s->size = size; - } else { - if (s2->expr->data.string.size > tptr->size) { - if (copts.cplusplus || (s2->expr->data.string.size - 1) > tptr->size) - CError_Error(CErrorStr147); - s2->expr->data.string.size = tptr->size; - size = tptr->size; - } - memcpy(s->buffer + s->size, s2->expr->data.string.data, size); - } - } else { - if (!flag && errorflag) { - CError_Error(CErrorStr174); - return; - } - - start = s->size; - i = 0; - while (1) { - if (is_zero_size) { - size = (i + 1) * targetsize; - s->size = start + size - targetsize - s->xC; - if (s->size + targetsize > s->bufferSize) - s = CInit_GrowBuffer(s, targetsize * 16); - CInit_InitType(s, s2, tptr->target, qual, 0); - tptr->size = size; - s->size = start + size - s->xC; - } else { - if (tptr->size <= i * targetsize) { - i--; - CError_Error(CErrorStr147); - } - s->size = start + i * targetsize; - CInit_InitType(s, s2, tptr->target, qual, 0); - if (!flag && tptr->size <= (i + 1) * targetsize) - break; - } - - switch (CInit_ParseNextInit(s2)) { - case Stage1: - case Stage2: - break; - case Stage3: - if (flag) - tk = lex(); - return; - default: - CError_Error(CErrorStr130); - return; - } - - i++; - } - } - - if (flag) { - switch (CInit_ParseNextInit(s2)) { - case Stage3: - tk = lex(); - return; - case Stage2: - CError_Error(CErrorStr147); - return; - default: - CError_Error(CErrorStr130); - } - } -} - -static void CInit_InitTypeStruct(CInit_Stuff *s, CInit_Stuff2 *s2, const TypeStruct *tstruct, UInt32 qual, Boolean errorflag) { - StructMember *member; - SInt32 start; - Boolean flag; - SInt32 count; - TypePointer arraytype; - MWVector128 *vecp; - int i; - - count = 0; - if (s2->type) - tstruct = TYPE_STRUCT(s2->type); - - if (!(member = tstruct->members)) { - CError_Error(CErrorStr145); - return; - } - - switch (s2->stage) { - case Stage1: - flag = 1; - if (CInit_ParseNextInit(s2) == Stage3) { - tk = lex(); - return; - } - break; - case Stage2: - flag = 0; - break; - } - - switch (s2->stage) { - case Stage1: - case Stage2: - break; - default: - CError_Error(CErrorStr174); - return; - } - - if (!flag && s2->stage == Stage2 && (errorflag || s2->expr->rtype == TYPE(tstruct))) { - s2->expr = CExpr_AssignmentPromotion(s2->expr, TYPE(tstruct), qual, 1); - if (IS_TYPE_STRUCT(s2->expr->rtype)) - CInit_InitNonConst(s, TYPE(tstruct), s2->expr); - return; - } - - start = s->size; - while (1) { - s->size = start + member->offset; - if (!member->type->size) { - if (!errorflag || !IS_TYPE_ARRAY(member->type)) { - CError_Error(CErrorStr147); - if (!IS_TYPE_ARRAY(member->type)) - return; - } - - arraytype = *TYPE_POINTER(member->type); - CInit_InitTypeArray(s, s2, &arraytype, member->qual, 1); - s->x18 = arraytype.size; - } else { - CInit_InitType(s, s2, member->type, member->qual, 0); - } - - count++; - if (IS_TYPESTRUCT_VECTOR(tstruct) && s2->expr) - CError_ASSERT(1218, !ENODE_IS(s2->expr, EVECTOR128CONST)); - - do { - member = member->next; - } while (member && (member->qual & Q_WEAK)); - - if (!member || tstruct->stype == STRUCT_TYPE_UNION) { - if (flag) { - switch (CInit_ParseNextInit(s2)) { - case Stage3: - if (IS_TYPESTRUCT_VECTOR(tstruct)) { - vecp = (MWVector128 *) (s->buffer + start); - CMach_InitVectorMem(TYPE(tstruct), *vecp, vecp, 0); - } - tk = lex(); - return; - case Stage2: - CError_Error(CErrorStr147); - return; - default: - CError_Error(CErrorStr130); - return; - } - } - return; - } else { - switch (CInit_ParseNextInit(s2)) { - case Stage1: - case Stage2: - continue; - case Stage3: - if (flag) - tk = lex(); - if (IS_TYPESTRUCT_VECTOR(tstruct)) { - switch (TYPE_STRUCT(tstruct)->stype) { - case STRUCT_VECTOR_UCHAR: - case STRUCT_VECTOR_SCHAR: - case STRUCT_VECTOR_BCHAR: - if (count != 16) { - if (count == 1) { - UInt8 val, *p; - p = (UInt8 *) s->buffer; - val = p[0]; - for (i = 1; i < 16; i++) - p[i] = val; - } else { - CError_Error(CErrorStr174); - } - } - break; - case STRUCT_VECTOR_USHORT: - case STRUCT_VECTOR_SSHORT: - case STRUCT_VECTOR_BSHORT: - case STRUCT_VECTOR_PIXEL: - if (count != 8) { - if (count == 1) { - SInt16 val, *p; - p = (SInt16 *) s->buffer; - val = p[0]; - for (i = 1; i < 8; i++) - p[i] = val; - } else { - CError_Error(CErrorStr174); - } - } - break; - case STRUCT_VECTOR_UINT: - case STRUCT_VECTOR_SINT: - case STRUCT_VECTOR_BINT: - case STRUCT_VECTOR_FLOAT: - if (count != 4) { - if (count == 1) { - UInt32 val, *p; - p = (UInt32 *) s->buffer; - val = p[0]; - for (i = 1; i < 4; i++) - p[i] = val; - } else { - CError_Error(CErrorStr174); - } - } - break; - } - } - return; - default: - CError_Error(CErrorStr174); - return; - } - } - } -} - -static ObjMemberVar *CInit_FindNextMember(ObjMemberVar *ivar) { - ObjMemberVar *scan = ivar; - while (1) { - scan = scan->next; - if (!scan) - return NULL; - if (!scan->anonunion) - return scan; - if (scan->offset > ivar->offset) - return scan; - if (IS_TYPE_BITFIELD(scan->type) && IS_TYPE_BITFIELD(ivar->type) && TYPE_BITFIELD(scan->type)->offset != TYPE_BITFIELD(ivar->type)->offset) - return scan; - } -} - -static void CInit_InitTypeClass(CInit_Stuff *s, CInit_Stuff2 *s2, TypeClass *tclass, UInt32 qual, Boolean errorflag) { - ObjMemberVar *ivar; - SInt32 start; - Boolean flag; - SInt32 last_offset; - TypePointer arraytype; - - if (tclass->bases || tclass->vtable) { - CError_Error(CErrorStr174); - return; - } - - switch (s2->stage) { - case Stage1: - flag = 1; - if (CInit_ParseNextInit(s2) == Stage3) { - tk = lex(); - return; - } - break; - case Stage2: - flag = 0; - break; - } - - switch (s2->stage) { - case Stage1: - case Stage2: - break; - default: - CError_Error(CErrorStr174); - return; - } - - if (!flag && s2->stage == Stage2 && (errorflag || s2->expr->rtype == TYPE(tclass) || CExpr_CanImplicitlyConvert(s2->expr, TYPE(tclass), 0))) { - s2->expr = CExpr_AssignmentPromotion(s2->expr, TYPE(tclass), qual, 1); - if (IS_TYPE_CLASS(s2->expr->rtype)) - CInit_InitNonConst(s, TYPE(tclass), s2->expr); - return; - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - if (ivar->access != ACCESSPUBLIC) { - CError_Error(CErrorStr174); - break; - } - } - - if (!(ivar = tclass->ivars)) { - CError_Error(CErrorStr147); - return; - } - start = s->size; - while (1) { - s->size = start + ivar->offset; - if (!ivar->type->size) { - if (!errorflag || !IS_TYPE_ARRAY(ivar->type)) { - CError_Error(CErrorStr147); - if (!IS_TYPE_ARRAY(ivar->type)) - return; - } - - arraytype = *TYPE_POINTER(ivar->type); - CInit_InitTypeArray(s, s2, &arraytype, ivar->qual, 1); - s->x18 = arraytype.size; - } else { - CInit_InitType(s, s2, ivar->type, ivar->qual, 0); - } - - last_offset = ivar->offset; - if (!(ivar = CInit_FindNextMember(ivar)) || (tclass->mode == CLASS_MODE_UNION && ivar->offset == last_offset)) { - if (flag) { - switch (CInit_ParseNextInit(s2)) { - case Stage3: - tk = lex(); - return; - case Stage2: - CError_Error(CErrorStr147); - return; - default: - CError_Error(CErrorStr130); - return; - } - } - return; - } else { - switch (CInit_ParseNextInit(s2)) { - case Stage1: - case Stage2: - continue; - case Stage3: - if (flag) - tk = lex(); - break; - default: - CError_Error(CErrorStr174); - } - return; - } - } -} - -static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32 qual, Boolean errorflag) { - Boolean flag; - - switch (type->type) { - case TYPEVOID: - CError_Error(CErrorStr174); - break; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEBITFIELD: - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - switch (s2->stage) { - case Stage1: - flag = 1; - CInit_ParseNextInit(s2); - break; - case Stage2: - flag = 0; - break; - } - if (s2->stage != Stage2) { - CError_Error(CErrorStr174); - return; - } - - switch (type->type) { - case TYPEINT: - CInit_InitTypeInt(s, s2->expr, TYPE_INTEGRAL(type), qual); - break; - case TYPEFLOAT: - CInit_InitTypeFloat(s, s2->expr, TYPE_INTEGRAL(type), qual); - break; - case TYPEENUM: - CInit_InitTypeEnum(s, s2->expr, TYPE_ENUM(type), qual); - break; - case TYPEPOINTER: - CInit_InitTypePointer(s, s2->expr, TYPE_POINTER(type), qual); - break; - case TYPEMEMBERPOINTER: - CInit_InitTypeMemberPointer(s, s2->expr, TYPE_MEMBER_POINTER(type), qual); - break; - case TYPEBITFIELD: - CInit_InitTypeBitfield(s, s2->expr, TYPE_BITFIELD(type), qual); - break; - default: - CError_FATAL(1542); - } - - if (flag) { - switch (CInit_ParseNextInit(s2)) { - case Stage3: - tk = lex(); - break; - case Stage2: - CError_Error(CErrorStr147); - break; - default: - CError_Error(CErrorStr130); - } - } - break; - case TYPESTRUCT: - CInit_InitTypeStruct(s, s2, TYPE_STRUCT(type), qual, errorflag); - break; - case TYPEARRAY: - CInit_InitTypeArray(s, s2, TYPE_POINTER(type), qual, errorflag); - break; - case TYPECLASS: - CInit_InitTypeClass(s, s2, TYPE_CLASS(type), qual, errorflag); - break; - default: - CError_FATAL(1573); - } -} - -static void CInit_InitData(CInit_Stuff *s, Type *type, UInt32 qual, Boolean flag) { - CInit_Stuff2 s2; - SInt32 size; - CInit_Stuff *tmp; - char *buffer; - - locklheap(); - memclrw(s, sizeof(CInit_Stuff)); - s->x4 = s; - if (type->size == 0) { - if (IS_TYPE_ARRAY(type)) - s->bufferSize = 16 * TYPE_POINTER(type)->target->size; - else - CError_Error(CErrorStr145); - } else { - s->bufferSize = type->size; - } - - s->buffer = lalloc(s->bufferSize); - memset(s->buffer, 0, s->bufferSize); - s->flag = flag; - - s2.stage = Stage0; - s2.x23 = 0; - if (IS_TYPE_VECTOR(type)) { - s2.x23 = 1; - s->flag = 1; - } - if (IS_TYPE_ARRAY(type) && IS_TYPE_VECTOR(TYPE_POINTER(type)->target)) { - s->flag = 1; - } - - s2.type = NULL; - s2.x24 = 0; - CInit_ParseNextInit(&s2); - CInit_InitType(s, &s2, type, qual, 1); - - if ((size = type->size + s->x18)) { - if (s->x0) { - buffer = lalloc(size); - for (tmp = s; tmp; tmp = tmp->x0) { - CError_ASSERT(1647, (tmp->xC + tmp->size) <= size); - memcpy(buffer + tmp->xC, tmp->buffer, tmp->size); - } - s->buffer = buffer; - } - } else { - CError_Error(CErrorStr174); - } - - s->size = size; - s->x0 = NULL; - unlocklheap(); -} - -static ENode *CInit_InitConcat(ENode *a1, ENode *a2, SInt32 offset, Type *type, ENode *a5) { - ENode *r30; - ENode *r28; - ENode *tmp; - - r28 = lalloc(sizeof(ENode)); - *r28 = *a2; - if (offset) - r28 = makediadicnode(r28, intconstnode(TYPE(&stunsignedlong), offset), EADD); - - if (IS_TYPE_BITFIELD(type)) { - tmp = makemonadicnode(r28, EBITFIELD); - tmp->rtype = type; - tmp = makemonadicnode(tmp, EINDIRECT); - tmp->rtype = TYPE_BITFIELD(type)->bitfieldtype; - } else { - tmp = makemonadicnode(r28, EINDIRECT); - tmp->rtype = type; - } - - r30 = makediadicnode(tmp, a5, EASS); - if (!a1) { - return r30; - } else { - tmp = makediadicnode(a1, r30, ECOMMA); - tmp->rtype = r30->rtype; - return tmp; - } -} - -static ENode *CInit_RegisterDtorObject(Type *type, Object *dtor, ENode *objexpr) { - ENode *expr; - - if (copts.no_static_dtors) - return objexpr; - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 4; - expr->flags = 0; - expr->rtype = CDecl_NewPointerType(type); - expr->data.funccall.funcref = create_objectrefnode(Xgreg_func); - expr->data.funccall.functype = TYPE_FUNC(Xgreg_func->type); - expr->data.funccall.args = lalloc(sizeof(ENodeList)); - expr->data.funccall.args->node = objexpr; - expr->data.funccall.args->next = lalloc(sizeof(ENodeList)); - expr->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); - expr->data.funccall.args->next->next = lalloc(sizeof(ENodeList)); - expr->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType())); - expr->data.funccall.args->next->next->next = NULL; - - return expr; -} - -static Boolean CInit_ConstructGlobalObject(Object *obj, TypeClass *tclass, ENode *valueexpr, SInt32 offset, Boolean flag) { - NameSpaceObjectList *ctor; - Object *dtor; - ENodeList *list; - ENode *expr; - Boolean ctorflag; - - ctor = CClass_Constructor(tclass); - dtor = CClass_Destructor(tclass); - if (!ctor && !dtor) - return 0; - - if (flag && !ctor && tk == '=' && lookahead() == '{') - return 0; - - if (flag && tk == '(') { - tk = lex(); - list = CExpr_ScanExpressionList(1); - if (tk == ')') - tk = lex(); - else - CError_Error(CErrorStr115); - } else if (valueexpr) { - list = lalloc(sizeof(ENodeList)); - list->node = valueexpr; - list->next = NULL; - } else { - list = NULL; - } - - expr = create_objectrefnode(obj); - if (offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); - - if (ctor) { - ctorflag = 1; - if (tk == '=') { - ctorflag = 0; - if (list) - CError_Error(CErrorStr174); - - list = lalloc(sizeof(ENodeList)); - list->next = NULL; - tk = lex(); - list->node = conv_assignment_expression(); - } - - expr = CExpr_ConstructObject(tclass, expr, list, 0, 1, 0, 1, ctorflag); - if (expr->rtype->type != TYPEPOINTER) { - CError_Error(CErrorStr174); - return 1; - } - } else { - if (list) - CError_Error(CErrorStr174); - } - - if (dtor) - expr = CInit_RegisterDtorObject(TYPE(tclass), dtor, expr); - - if (cinit_initinfo->x16) - cinit_initinfo->init_expr_register_cb(expr); - else - InitExpr_Register(expr, obj); - - return 1; -} - -static Boolean CInit_ConstructAutoObject(TypeClass *tclass, ENode *expr, SInt32 offset, Boolean flag) { - ENodeList *r30; - ENode *r29; - NameSpaceObjectList *ctor; - Object *dtor; - Boolean r24; - - ctor = CClass_Constructor(tclass); - dtor = CClass_Destructor(tclass); - if (!ctor && !dtor) - return 0; - - if (dtor) - CClass_CheckStaticAccess(NULL, tclass, dtor->access); - - if (flag && !ctor && tk == '=' && lookahead() == '{') - return 0; - - if (flag && tk == '(') { - tk = lex(); - r30 = CExpr_ScanExpressionList(1); - if (tk == ')') - tk = lex(); - else - CError_Error(CErrorStr115); - } else if (expr) { - r30 = lalloc(sizeof(ENodeList)); - r30->node = expr; - r30->next = NULL; - } else { - r30 = NULL; - } - - if (ctor) { - r24 = 1; - if (tk == '=') { - if (r30) - CError_Error(CErrorStr174); - r30 = lalloc(sizeof(ENodeList)); - r30->next = NULL; - tk = lex(); - r30->node = conv_assignment_expression(); - r24 = 0; - } - - if (!dtor) { - r29 = create_objectrefnode(cinit_initinfo->obj1C); - if (offset) - r29 = makediadicnode(r29, intconstnode(TYPE(&stunsignedlong), offset), EADD); - } else { - r29 = cinit_initinfo->register_object_cb(TYPE(tclass), cinit_initinfo->obj1C, offset, 0); - } - - r29 = CExpr_ConstructObject(tclass, r29, r30, 0, 1, 0, 1, r24); - if (!IS_TYPE_POINTER_ONLY(r29->rtype)) { - CError_Error(CErrorStr174); - return 1; - } - r29 = makemonadicnode(r29, EINDIRECT); - r29->rtype = TYPE_POINTER(r29->rtype)->target; - cinit_initinfo->insert_expr_cb(r29); - } else { - if (r30) - CError_Error(CErrorStr174); - if (dtor) - r29 = cinit_initinfo->register_object_cb(TYPE(tclass), cinit_initinfo->obj1C, offset, 0); - cinit_initinfo->insert_expr_cb(r29); - } - - return 1; -} - -static void CInit_ExprPointer(TypePointer *tptr, ENode *expr) { - Object *obj; - CInt64 val; - OLinkList *list; - - if (CInit_RelocInitCheck(expr, &obj, &val, 0)) { - if (obj) { - list = lalloc(sizeof(OLinkList)); - list->next = cinit_initinfo->list; - list->obj = obj; - list->somevalue = CInt64_GetULong(&val); - list->offset = cinit_initinfo->expr_offset; - cinit_initinfo->list = list; - } else { - CMach_InitIntMem(TYPE(&stunsignedlong), val, cinit_initinfo->buffer + cinit_initinfo->expr_offset); - } - } else if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(TYPE(tptr), expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - - cinit_initinfo->expr_offset += 4; -} - -static void CInit_ExprInt(TypeIntegral *tint, ENode *expr) { - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(TYPE(tint), expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset); - } else if (ENODE_IS(expr, ETYPCON) && IS_TYPE_POINTER_ONLY(expr->data.monadic->rtype) && expr->rtype->size == 4 && (copts.cplusplus || !copts.ANSIstrict)) { - CInit_ExprPointer(TYPE_POINTER(expr->data.monadic->rtype), expr->data.monadic); - } else if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(TYPE(tint), expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - - cinit_initinfo->expr_offset += tint->size; -} - -static void CInit_ExprFloat(TypeIntegral *tint, ENode *expr) { - if (ENODE_IS(expr, EFLOATCONST)) { - CMach_InitFloatMem(TYPE(tint), expr->data.floatval, cinit_initinfo->buffer + cinit_initinfo->expr_offset); - } else if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(TYPE(tint), expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - - cinit_initinfo->expr_offset += tint->size; -} - -static void CInit_ExprEnum(TypeEnum *tenum, ENode *expr) { - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(tenum->enumtype, expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset); - } else if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(TYPE(tenum), expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - - cinit_initinfo->expr_offset += tenum->size; -} - -static void CInit_ExprMemberPointer(TypeMemberPointer *tmptr, ENode *expr) { - if (ENODE_IS(expr, EINTCONST)) { - CMach_InitIntMem(TYPE(&stsignedlong), expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset); - } else if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(TYPE(tmptr), expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - - cinit_initinfo->expr_offset += tmptr->size; -} - -static void CInit_TypeExpr(Type *type, ENode *expr) { - switch (type->type) { - case TYPEINT: - CInit_ExprInt(TYPE_INTEGRAL(type), expr); - break; - case TYPEFLOAT: - CInit_ExprFloat(TYPE_INTEGRAL(type), expr); - break; - case TYPEENUM: - CInit_ExprEnum(TYPE_ENUM(type), expr); - break; - case TYPEPOINTER: - CInit_ExprPointer(TYPE_POINTER(type), expr); - break; - case TYPEMEMBERPOINTER: - CInit_ExprMemberPointer(TYPE_MEMBER_POINTER(type), expr); - break; - case TYPESTRUCT: - case TYPECLASS: - if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(type, expr, 0); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr124); - } - break; - case TYPEARRAY: - CError_Error(CErrorStr174); - break; - default: - CError_FATAL(2082); - } -} - -static void CInit_Bitfield(TypeBitfield *tbitfield) { - Boolean r30; - ENode *expr; - ENode myexpr; - - r30 = tk == '{'; - if (r30) - tk = lex(); - - expr = CInit_ParseInitializer(&myexpr); - expr = CExpr_AssignmentPromotion( - expr, - IS_TYPE_ENUM(tbitfield->bitfieldtype) ? TYPE_ENUM(tbitfield->bitfieldtype)->enumtype : tbitfield->bitfieldtype, - 0, - 1); - if (ENODE_IS(expr, EINTCONST)) - CInit_SetBitfield(tbitfield, (UInt8 *) cinit_initinfo->buffer + cinit_initinfo->expr_offset, expr->data.intval); - else - CError_Error(CErrorStr124); - - if (r30) - CInit_CloseInitList(); -} - -static void CInit_Array(TypePointer *tptr, UInt32 qual, Boolean flag) { - SInt32 start; - SInt32 i; - SInt32 targetsize1; - SInt32 targetsize2; - Boolean in_block; - Boolean is_char_ptr; - Boolean needs_construction; - Boolean is_wchar_ptr; - - targetsize1 = tptr->target->size; - targetsize2 = tptr->target->size; - if (!tptr->target->size) { - if (!IS_TYPE_ARRAY(tptr->target)) { - CError_Error(CErrorStr145); - return; - } - targetsize1 = tptr->target->size; - targetsize2 = tptr->target->size; - if (!tptr->target->size) { - CError_Error(CErrorStr145); - return; - } - } - - is_char_ptr = IS_TYPE_INT(tptr->target) && (tptr->target->size == 1); - is_wchar_ptr = IS_TYPE_INT(tptr->target) && (tptr->target->size == stwchar.size); - - in_block = 1; - if (flag && !(tk == TK_STRING && is_char_ptr) && !(tk == TK_STRING_WIDE && is_wchar_ptr)) { - if (tk != '{') { - CError_ErrorSkip(CErrorStr135); - return; - } - tk = lex(); - } else { - if (tk == '{') - tk = lex(); - else - in_block = 0; - } - - if ((tk == TK_STRING && is_char_ptr) || (tk == TK_STRING_WIDE && is_wchar_ptr)) { - if (tptr->size) { - if (tksize > tptr->size) { - if (copts.cplusplus || (tksize - (is_wchar_ptr ? stwchar.size : 1)) > tptr->size) - CError_Error(CErrorStr147); - tksize = tptr->size; - } - memcpy(cinit_initinfo->buffer + cinit_initinfo->expr_offset, tkstring, tksize); - } else { - tptr->size = tksize; - CInit_SetData(tkstring, cinit_initinfo->expr_offset, tptr->size); - } - cinit_initinfo->expr_offset += tptr->size; - tk = lex(); - if (in_block) - CInit_CloseInitList(); - return; - } - - if (IS_TYPE_CLASS(tptr->target) && CInit_ClassNeedsConstruction(TYPE_CLASS(tptr->target))) - needs_construction = 1; - else - needs_construction = 0; - - start = cinit_initinfo->expr_offset; - i = 0; - while (1) { - if (tk == '}') { - innerloop: - if (tptr->size) { - if (needs_construction) { - while (tptr->size > (i * targetsize1)) { - cinit_initinfo->expr_offset = start + i * targetsize2; - if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(tptr->target, NULL, 1); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr174); - } - i++; - } - } - } else { - tptr->size = i * targetsize1; - } - cinit_initinfo->expr_offset = start + tptr->size; - if (in_block) - tk = lex(); - return; - } - - if (!tptr->size) { - cinit_initinfo->expr_offset = start + i * targetsize2; - CInit_SetData(NULL, cinit_initinfo->expr_offset, targetsize2); - if (needs_construction) { - if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(tptr->target, conv_assignment_expression(), 1); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr174); - } - } else { - CInit_Type(tptr->target, qual, 0); - } - } else { - if (tptr->size <= i * targetsize1) { - i--; - CError_Error(CErrorStr147); - } - - cinit_initinfo->expr_offset = start + i * targetsize2; - if (needs_construction) { - if (cinit_initinfo->expr_cb) { - cinit_initinfo->expr_cb(tptr->target, conv_assignment_expression(), 1); - cinit_initinfo->expr_cb_called = 1; - } else { - CError_Error(CErrorStr174); - } - } else { - CInit_Type(tptr->target, qual, 0); - } - - if (!in_block) { - if (tptr->size <= (i + 1) * targetsize1) - return; - } - } - - if (tk != '}') { - if (tk != ',') { - CError_ErrorSkip(CErrorStr121); - in_block = 0; - i++; - goto innerloop; - } - tk = lex(); - } - i++; - } -} - -static void CInit_Struct(TypeStruct *tstruct, Boolean flag) { - StructMember *member; - SInt32 start; - Boolean in_block; - - if (!(member = tstruct->members)) { - CError_Error(CErrorStr145); - return; - } - - if (tstruct->stype == STRUCT_TYPE_UNION) { - if (tk == '{') { - tk = lex(); - CInit_Type(member->type, member->qual, 0); - if (tk == '}') - tk = lex(); - } else { - CInit_Type(member->type, member->qual, 0); - } - return; - } - - if (IS_TYPE_VECTOR(tstruct) && tk != '{') { - CInit_TypeExpr(TYPE(tstruct), CExpr_AssignmentPromotion(conv_assignment_expression(), TYPE(tstruct), 0, 1)); - return; - } - - if (tk != '{') { - if (flag) - CError_ErrorSkip(CErrorStr135); - in_block = 0; - } else { - in_block = 1; - tk = lex(); - } - - start = cinit_initinfo->expr_offset; - while (1) { - if (tk == '}') - break; - - cinit_initinfo->expr_offset = start + member->offset; - if (!member->type->size && IS_TYPE_ARRAY(member->type)) { - CError_Error(CErrorStr147); - break; - } - - CInit_Type(member->type, member->qual, 0); - if (tk == '}') - break; - - if (tk != ',') { - CError_Error(CErrorStr121); - break; - } - - do { - member = member->next; - } while (member && (member->qual & Q_WEAK)); - - if (!member) { - if (!in_block) - break; - if ((tk = lex()) != '}') { - CError_Error(CErrorStr147); - break; - } - } else { - tk = lex(); - } - } - - cinit_initinfo->expr_offset = start + tstruct->size; - if (tk == '}' && in_block) - tk = lex(); -} - -static void CInit_Class(TypeClass *tclass, Boolean flag) { - ObjMemberVar *ivar; - SInt32 start; - Boolean in_block; - - if (tk == '{') { - in_block = 1; - tk = lex(); - } else { - in_block = 0; - } - - if (tclass->bases || tclass->vtable) { - CError_Error(CErrorStr174); - return; - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - if (ivar->access != ACCESSPUBLIC) - break; - } - - if (!ivar && !CClass_Constructor(tclass) && (!CClass_Destructor(tclass) || in_block)) { - if ((ivar = tclass->ivars)) { - start = cinit_initinfo->expr_offset; - while (1) { - if (tk == '}') - break; - - if (!ivar->type->size && IS_TYPE_ARRAY(ivar->type)) { - CError_Error(CErrorStr147); - break; - } - - cinit_initinfo->expr_offset = start + ivar->offset; - CInit_Type(ivar->type, ivar->qual, 0); - - if (tk == '}') - break; - - if (tk != ',') { - CError_Error(CErrorStr121); - break; - } - - do { - ivar = ivar->next; - } while (ivar && ivar->anonunion); - - if (!ivar) { - if (!in_block) - break; - if ((tk = lex()) != '}') { - CError_Error(CErrorStr147); - break; - } - } else { - tk = lex(); - } - } - } else { - if (in_block && tk != '}') - CError_Error(CErrorStr147); - } - } else { - if (in_block) - CError_Error(CErrorStr174); - CInit_TypeExpr(TYPE(tclass), CExpr_AssignmentPromotion(conv_assignment_expression(), TYPE(tclass), 0, 1)); - } - - cinit_initinfo->expr_offset = start + tclass->size; - if (tk == '}' && in_block) - tk = lex(); -} - -static void CInit_Type(Type *type, UInt32 qual, Boolean flag) { - ENode *expr; - ENode myexpr; - - switch (type->type) { - case TYPEVOID: - CError_Error(CErrorStr174); - break; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEPOINTER: - case TYPEMEMBERPOINTER: - if (tk == '{') { - tk = lex(); - expr = CInit_ParseInitializer(&myexpr); - expr = CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1); - CInit_CloseInitList(); - } else { - expr = CInit_ParseInitializer(&myexpr); - expr = CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1); - } - CInit_TypeExpr(type, expr); - break; - case TYPEBITFIELD: - CInit_Bitfield(TYPE_BITFIELD(type)); - break; - case TYPEARRAY: - CInit_Array(TYPE_POINTER(type), qual, flag); - break; - case TYPESTRUCT: - CInit_Struct(TYPE_STRUCT(type), flag); - break; - case TYPECLASS: - CInit_Class(TYPE_CLASS(type), flag); - break; - default: - CError_FATAL(2482); - } -} - -static void CInit_GlobalStaticInit(Type *type, ENode *valueexpr, Boolean flag) { - ENode *expr; - ENode *tmp; - - cinit_initinfo->x15 = 1; - if (flag) { - CInit_ConstructGlobalObject(cinit_initinfo->obj, TYPE_CLASS(type), valueexpr, cinit_initinfo->expr_offset, 0); - } else { - expr = create_objectrefnode(cinit_initinfo->obj); - if (!IS_TYPE_POINTER_ONLY(expr->rtype)) { - CError_Error(CErrorStr174); - return; - } - TYPE_POINTER(expr->rtype)->target = type; - - if (cinit_initinfo->expr_offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD); - - tmp = makemonadicnode(expr, EINDIRECT); - tmp->rtype = type; - expr = makediadicnode(tmp, valueexpr, EASS); - if (cinit_initinfo->x16) - cinit_initinfo->init_expr_register_cb(expr); - else - InitExpr_Register(expr, cinit_initinfo->obj); - } -} - -static void CInit_AutoInit(Type *type, ENode *valueexpr, Boolean flag) { - ENode *expr; - ENode *tmp; - Type *copy; - SInt32 size; - - if (flag) { - CInit_ConstructAutoObject(TYPE_CLASS(type), valueexpr, cinit_initinfo->expr_offset, 0); - } else { - if (IS_TYPE_ARRAY(type) && (type->size & 1)) { - copy = galloc(sizeof(TypePointer)); - *TYPE_POINTER(copy) = *TYPE_POINTER(type); - type = copy; - copy->size++; - } - expr = create_objectrefnode(cinit_initinfo->obj1C); - if (!IS_TYPE_POINTER_ONLY(expr->rtype)) { - CError_Error(CErrorStr174); - return; - } - TYPE_POINTER(expr->rtype)->target = type; - - if (cinit_initinfo->expr_offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD); - - tmp = makemonadicnode(expr, EINDIRECT); - tmp->rtype = type; - expr = makediadicnode(tmp, valueexpr, EASS); - if (!copts.cplusplus) - CError_Error(CErrorStr124); - cinit_initinfo->insert_expr_cb(expr); - } -} - -static SInt32 CInit_AdjustObjectDataSize(Object *obj) { - if (obj->type->size <= 1) - return obj->type->size; - if (obj->type->size & 1) - return obj->type->size + 1; - else - return obj->type->size; -} - -static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB expr_cb, Boolean flag) { - Object *r31; - ENode *expr; - ENode *tmpexpr; - Type *inner; - Type *copy; - SInt32 size; - Boolean lastflag; - SInt16 cv; - - cinit_initinfo->expr_cb = expr_cb; - expr = NULL; - - if (tk == '(') { - if (IS_TYPE_ARRAY(type)) - CError_Error(CErrorStr174); - tk = lex(); - expr = CExpr_AssignmentPromotion(assignment_expression(), type, qual, 1); - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - goto jump_ahead; - } - - tk = lex(); - switch (type->type) { - case TYPECLASS: - if (tk == '{' && CClass_Constructor(TYPE_CLASS(type))) - CError_Error(CErrorStr174); - case TYPESTRUCT: - if (tk != '{') - goto generic_type; - case TYPEARRAY: - if (!obj) { - if (IS_TYPE_ARRAY(type)) { - inner = type; - while (IS_TYPE_ARRAY(inner)) - inner = TYPE_POINTER(inner)->target; - - if (IS_TYPE_CLASS(inner) && CInit_ClassNeedsConstruction(TYPE_CLASS(inner))) { - CInit_SetupInitInfoBuffer(type); - cinit_initinfo->obj = cinit_initinfo->obj1C; - CInit_Type(type, cinit_initinfo->obj->qual, 1); - return 0; - } - if (type->size & 1) { - copy = galloc(sizeof(TypePointer)); - *TYPE_POINTER(copy) = *TYPE_POINTER(type); - type = copy; - type->size++; - } - } - - obj = CInit_CreateStaticDataObject(type, qual, NULL); - cinit_initinfo->obj = obj; - expr = create_objectnode(obj); - cinit_initinfo->obj1C = obj; - } - CInit_SetupInitInfoBuffer(type); - CInit_Type(type, obj->qual, 1); - CError_ASSERT(2639, obj->type->size == (size = cinit_initinfo->size)); - if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, size)) { - CInit_AdjustObjectDataSize(obj); - CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size); - } else { - CInit_AdjustObjectDataSize(obj); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - return expr; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEPOINTER: - case TYPEMEMBERPOINTER: - generic_type: - if (obj) - cv = obj->qual & Q_CV; - else - cv = cinit_initinfo->obj1C->qual & Q_CV; - - if (tk == '{') { - tk = lex(); - expr = assignment_expression(); - CInit_CloseInitList(); - } else { - expr = assignment_expression(); - } - expr = CExpr_AssignmentPromotion(expr, type, cv, 1); - jump_ahead: - if (obj == NULL) - r31 = cinit_initinfo->obj1C; - else - r31 = obj; - - if (is_const_object(r31)) { - switch (r31->type->type) { - case TYPEINT: - case TYPEENUM: - if (ENODE_IS(expr, EINTCONST)) { - r31->u.data.u.intconst = expr->data.intval; - goto common_8068C; - } - break; - case TYPEFLOAT: - if (ENODE_IS(expr, EFLOATCONST)) { - Float fl; - r31->u.data.u.floatconst = galloc(sizeof(Float)); - fl = CMach_CalcFloatConvert(r31->type, expr->data.floatval); - *r31->u.data.u.floatconst = fl; - goto common_8068C; - } - break; - case TYPEPOINTER: - tmpexpr = expr; - while (ENODE_IS(tmpexpr, ETYPCON)) - tmpexpr = tmpexpr->data.monadic; - if (!ENODE_IS(tmpexpr, EINTCONST)) - break; - r31->u.data.u.intconst = tmpexpr->data.intval; - common_8068C: - r31->qual |= Q_INLINE_DATA; - if (!obj) { - r31->sclass = TK_STATIC; - r31->datatype = DDATA; - r31->u.data.linkname = CParser_AppendUniqueName(r31->name->name); - } else if (r31->sclass != TK_STATIC || (r31->flags & OBJECT_FLAGS_2)) { - CInit_ExportConst(r31); - } - return NULL; - } - } - - if (!obj || (flag && copts.cplusplus)) { - if (obj) { - IsCompleteType(obj->type); - CError_ASSERT(2747, obj->type->size == type->size); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - return expr; - } - - CInit_SetupInitInfoBuffer(type); - CInit_TypeExpr(type, expr); - CError_ASSERT(2756, obj->type->size == cinit_initinfo->size); - - IsCompleteType(obj->type); - CInit_AdjustObjectDataSize(obj); - lastflag = !cinit_initinfo->x15 && is_const_object(r31); - if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) { - if (lastflag) - CInit_DeclareReadOnlyData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size); - else - CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size); - } else { - if (lastflag) - CInit_DeclareReadOnlyData(obj, NULL, NULL, obj->type->size); - else - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - break; - - default: - CError_FATAL(2776); - } - - return NULL; -} - -void CInit_ExportConst(Object *obj) { - char buffer[64]; - - if (obj->flags & OBJECT_DEFINED) - return; - - switch (obj->type->type) { - case TYPEINT: - CMach_InitIntMem(obj->type, obj->u.data.u.intconst, buffer); - break; - case TYPEENUM: - CMach_InitIntMem(TYPE_ENUM(obj->type)->enumtype, obj->u.data.u.intconst, buffer); - break; - case TYPEPOINTER: - CMach_InitIntMem(TYPE(&stunsignedlong), obj->u.data.u.intconst, buffer); - break; - case TYPEFLOAT: - CMach_InitFloatMem(obj->type, *obj->u.data.u.floatconst, buffer); - break; - default: - CError_FATAL(2807); - } - - if (is_const_object(obj)) - CInit_DeclareReadOnlyData(obj, buffer, NULL, obj->type->size); - else - CInit_DeclareData(obj, buffer, NULL, obj->type->size); -} - -static ENode *CInit_ClassInitLoopCallBack(ENode *expr) { - return CExpr_ConstructObject(cinit_loop_class, expr, NULL, 0, 1, 0, 1, 1); -} - -Statement *CInit_ConstructClassArray(Statement *stmt, TypeClass *tclass, Object *ctor, Object *dtor, ENode *firstarg, SInt32 count) { - ENode *dtor_expr; - - if (stmt) - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - else - stmt = CFunc_AppendStatement(ST_EXPRESSION); - - if (dtor) - dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); - else - dtor_expr = nullnode(); - - stmt->expr = CExpr_FuncCallSix( - carr_func, - firstarg, - create_objectrefnode(ctor), - dtor_expr, - intconstnode(TYPE(&stunsignedlong), tclass->size), - intconstnode(TYPE(&stunsignedlong), count), - NULL - ); - - return stmt; -} - -static void CInit_InitializeClassArray(Object *obj, TypeClass *tclass, Boolean flag) { - Object *ctor; - Object *dtor; - SInt32 count; - SInt32 i; - ENode *expr; - SInt32 offset; - ENode *dtor_expr; - Statement *stmt; - TypeFunc *tfunc; - Object *funcobj; - - dtor = CClass_Destructor(tclass); - count = obj->type->size / tclass->size; - if (CClass_Constructor(tclass)) { - ctor = CClass_DefaultConstructor(tclass); - if (!ctor) { - ctor = CClass_DummyDefaultConstructor(tclass); - if (!ctor) { - CError_Error(CErrorStr203); - return; - } - } - } else { - ctor = NULL; - } - - if (count <= 1 || (!flag && count <= 8)) { - if (flag) { - for (i = 0; i < count; i++) { - CInit_ConstructGlobalObject(obj, tclass, NULL, i * tclass->size, 0); - } - } else { - for (i = 0; i < count; i++) { - offset = i * tclass->size; - expr = create_objectrefnode(obj); - if (offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); - if (ctor) - expr = CExpr_ConstructObject(tclass, expr, NULL, 0, 1, 0, 1, 1); - cinit_initinfo->insert_expr_cb(expr); - if (dtor) - CExcept_RegisterDestructorObject(obj, offset, dtor, 1); - } - if (dtor) { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = nullnode(); - } - } - } else { - if (ctor) { - if (!flag && !dtor) { - CInit_ConstructClassArray(NULL, tclass, ctor, dtor, create_objectrefnode(obj), count); - expr = nullnode(); - } else { - if (dtor) - dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); - else - dtor_expr = nullnode(); - expr = CExpr_FuncCallSix( - carr_func, - create_objectrefnode(obj), - create_objectrefnode(ctor), - dtor_expr, - intconstnode(TYPE(&stunsignedlong), tclass->size), - intconstnode(TYPE(&stunsignedlong), count), - NULL - ); - } - } else { - expr = nullnode(); - } - - if (flag) { - if (dtor && !copts.no_static_dtors) { - tfunc = galloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - tfunc->type = TYPEFUNC; - tfunc->functype = &stvoid; - CDecl_SetFuncFlags(tfunc, 1); - - funcobj = CParser_NewCompilerDefFunctionObject(); - funcobj->name = CParser_AppendUniqueName("__arraydtor"); - funcobj->type = TYPE(tfunc); - funcobj->sclass = TK_STATIC; - funcobj->qual = Q_INLINE; - - CParser_RegisterSingleExprFunction(funcobj, funccallexpr( - darr_func, - create_objectrefnode(obj), - create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)), - intconstnode(TYPE(&stsignedlong), tclass->size), - intconstnode(TYPE(&stsignedlong), count) - )); - - expr = makediadicnode(expr, nullnode(), ECOMMA); - expr->rtype = TYPE(&void_ptr); - - expr = funccallexpr( - Xgreg_func, - expr, - create_objectrefnode(funcobj), - create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType())), - NULL - ); - } - if (cinit_initinfo->x16) - cinit_initinfo->init_expr_register_cb(expr); - else - InitExpr_Register(expr, obj); - } else { - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = expr; - if (dtor) { - CExcept_RegisterLocalArray(stmt, obj, dtor, count, tclass->size); - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = nullnode(); - } - } - } -} - -static ENode *CInit_AutoTempNode(Type *type, Boolean flag) { - ENode *node; - node = CExpr_NewETEMPNode(type, 0); - if (IS_TYPE_CLASS(type) && CClass_Destructor(TYPE_CLASS(type))) - node->data.temp.needs_dtor = 1; - return node; -} - -static ENode *CInit_GlobalTempNode(Type *type, Boolean flag) { - Object *dtor; - ENode *node; - ENode *funcnode; - - node = create_objectrefnode(CInit_CreateStaticData(type)); - if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type))) && !copts.no_static_dtors) { - if (flag) - CError_Error(CErrorStr190); - - funcnode = galloc(sizeof(ENode)); - funcnode->type = EFUNCCALL; - funcnode->cost = 200; - funcnode->flags = 0; - funcnode->rtype = CDecl_NewPointerType(type); - funcnode->data.funccall.funcref = create_objectrefnode(Xgreg_func); - funcnode->data.funccall.functype = TYPE_FUNC(Xgreg_func->type); - funcnode->data.funccall.args = lalloc(sizeof(ENodeList)); - funcnode->data.funccall.args->node = node; - funcnode->data.funccall.args->next = lalloc(sizeof(ENodeList)); - funcnode->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); - funcnode->data.funccall.args->next->next = lalloc(sizeof(ENodeList)); - funcnode->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType()));; - funcnode->data.funccall.args->next->next->next = NULL; - node = funcnode; - } - return node; -} - -static void CInit_RefInit(Type *type, ENode *expr, Boolean flag) { - ENode *objexpr; - - objexpr = create_objectrefnode(cinit_initinfo->obj); - if (!IS_TYPE_POINTER_ONLY(objexpr->rtype)) { - CError_Error(CErrorStr174); - return; - } - TYPE_POINTER(objexpr->rtype)->target = type; - - if (cinit_initinfo->expr_offset) - objexpr = makediadicnode(objexpr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD); - - objexpr = makemonadicnode(objexpr, EINDIRECT); - objexpr->rtype = type; - - expr = makediadicnode(objexpr, expr, EASS); - if (cinit_initinfo->x16) - cinit_initinfo->init_expr_register_cb(expr); - else - InitExpr_Register(expr, cinit_initinfo->obj); -} - -static Boolean CInit_IsDtorTemp(ENode *expr) { - return ENODE_IS(expr, ETEMP) && expr->data.temp.needs_dtor; -} - -static void CInit_FindDtorTemp(ENode *expr) { - ENodeList *list; - - while (ENODE_IS(expr, ECOMMA)) - expr = expr->data.diadic.right; - - if (IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_CLASS(TYPE_POINTER(expr->rtype)->target)) { - switch (expr->type) { - case ETYPCON: - CInit_FindDtorTemp(expr->data.monadic); - break; - case EADD: - case ESUB: - CInit_FindDtorTemp(expr->data.diadic.left); - CInit_FindDtorTemp(expr->data.diadic.right); - break; - case EFUNCCALL: - case EFUNCCALLP: - if ((list = expr->data.funccall.args)) { - if (CInit_IsDtorTemp(list->node) || ((list = list->next) && CInit_IsDtorTemp(list->node))) { - if (!cinit_fdtnode) - cinit_fdtnode = list; - else - cinit_fdtambig = 1; - } - } - break; - } - } -} - -static void CInit_RefTempTransform(Type *type, ENode *expr) { - Object *obj; - - CError_ASSERT(3164, IS_TYPE_POINTER_ONLY(type)); - - if (IS_TYPE_CLASS(TYPE_POINTER(type)->target)) { - cinit_fdtnode = NULL; - cinit_fdtambig = 0; - CInit_FindDtorTemp(expr); - if (cinit_fdtnode) { - CError_ASSERT(3172, !cinit_fdtambig); - obj = create_temp_object(cinit_fdtnode->node->data.temp.type); - cinit_initinfo->register_object_cb(cinit_fdtnode->node->data.temp.type, obj, 0, 0); - cinit_fdtnode->node = create_objectrefnode(obj); - } - } -} - -static Boolean CInit_InitReference(Object *obj, Boolean flag) { - ENode *expr; - - if (tk == '=') { - cinit_tempnodefunc = flag ? CInit_AutoTempNode : CInit_GlobalTempNode; - tk = lex(); - expr = CExpr_AssignmentPromotion(assignment_expression(), obj->type, obj->qual & (Q_CONST | Q_VOLATILE), 1); - cinit_tempnodefunc = NULL; - - if (flag) { - CInit_RefTempTransform(obj->type, expr); - expr = makediadicnode(create_objectnode2(obj), expr, EASS); - cinit_initinfo->insert_expr_cb(expr); - } else { - cinit_initinfo->expr_cb = CInit_RefInit; - CInit_SetupInitInfoBuffer(obj->type); - CInit_ExprPointer(TYPE_POINTER(obj->type), expr); - CError_ASSERT(3213, obj->type->size == cinit_initinfo->size); - - if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) { - IsCompleteType(obj->type); - CInit_AdjustObjectDataSize(obj); - CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size); - } else { - IsCompleteType(obj->type); - CInit_AdjustObjectDataSize(obj); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - } - - return 1; - } - - return 0; -} - -ENode *CInit_AutoObject(Object *obj, Type *type, UInt32 qual) { - CInit_Stuff s; - CInit_1C *entry; - ENode *expr; - ENode *indirect_expr; - ENode *obj_expr; - ENode *const_expr; - Type *newtype; - Object *newobj; - - CInit_InitData(&s, type, qual, copts.cplusplus || copts.gcc_extensions || copts.c9x || !obj); - if (!obj && !cscope_currentfunc) { - obj = CParser_NewCompilerDefDataObject(); - obj->name = CParser_GetUniqueName(); - obj->type = type; - obj->qual = qual; - obj->sclass = TK_STATIC; - CScope_AddGlobalObject(obj); - } - - if (IS_TYPE_VECTOR(type) && !s.x1C) { - if (obj) - obj_expr = create_objectrefnode(obj); - else - obj_expr = CExpr_NewETEMPNode(type, 1); - - const_expr = CExpr_NewENode(EVECTOR128CONST); - const_expr->rtype = type; - const_expr->data.vector128val = *((MWVector128 *) s.buffer); - - indirect_expr = makemonadicnode(obj_expr, EINDIRECT); - indirect_expr->rtype = type; - - expr = makediadicnode(indirect_expr, const_expr, EASS); - if (!obj) { - ENode *tmp = lalloc(sizeof(ENode)); - *tmp = *obj_expr; - tmp = makemonadicnode(tmp, EINDIRECT); - tmp->rtype = type; - tmp->flags = qual & ENODE_FLAG_QUALS; - expr = makecommaexpression(expr, tmp); - } - return expr; - } - - if (s.x18) { - type = CDecl_NewStructType(type->size + s.x18, CMach_GetTypeAlign(type)); - if (obj) - obj->type = type; - } - - if (obj) - obj_expr = create_objectrefnode(obj); - else - obj_expr = CExpr_NewETEMPNode(type, 1); - - newtype = type; - if (IS_TYPE_ARRAY(type)) - newtype = CDecl_NewStructType(type->size, CMach_GetTypeAlign(type)); - newobj = CInit_CreateStaticDataObject(newtype, 0, NULL); - if (s.list || !CInit_IsAllZero(s.buffer, s.size)) - CInit_DeclareReadOnlyData(newobj, s.buffer, s.list, s.size); - else - CInit_DeclareReadOnlyData(newobj, NULL, NULL, s.size); - - indirect_expr = makemonadicnode(obj_expr, EINDIRECT); - indirect_expr->rtype = newtype; - expr = makediadicnode(indirect_expr, create_objectnode(newobj), EASS); - - for (entry = s.x1C; entry; entry = entry->next) { - expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr); - } - - if (!obj) { - ENode *tmp = lalloc(sizeof(ENode)); - *tmp = *obj_expr; - tmp = makemonadicnode(tmp, EINDIRECT); - tmp->rtype = type; - tmp->flags = qual & ENODE_FLAG_QUALS; - expr = makecommaexpression(expr, tmp); - } else if (IS_TYPE_ARRAY(type)) { - expr = makecommaexpression(expr, create_objectnode(obj)); - } - - return expr; -} - -static void CInit_GlobalObject(Object *obj) { - CInit_Stuff s; - CInit_1C *entry; - ENode *obj_expr; - ENode *expr; - - CInit_InitData(&s, obj->type, obj->qual, copts.cplusplus); - obj_expr = create_objectrefnode(obj); - - IsCompleteType(obj->type); - - if (!s.x1C && is_const_object(obj)) - CInit_DeclareReadOnlyData(obj, s.buffer, s.list, s.size); - else - CInit_DeclareData(obj, s.buffer, s.list, s.size); - - if (s.x1C) { - entry = s.x1C; - expr = NULL; - while (entry) { - if (!ENODE_IS(entry->expr, EVECTOR128CONST)) - expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr); - entry = entry->next; - } - - if (expr) - InitExpr_Register(expr, obj); - } -} - -void CInit_InitializeAutoData(Object *obj, InsertExprCB insert_cb, RegisterObjectCB register_cb) { - ENode *expr; - Type *type; - InitInfo initinfo; - - if (CInit_IsSimpleStructArrayInit(obj->type)) { - if (tk == '=' || (tk == '(' && copts.cplusplus)) { - if (tk == '(') { - tk = lex(); - expr = conv_assignment_expression(); - if (tk != ')') - CError_Error(CErrorStr115); - tk = lex(); - } else if (tk == '=' && ((tk = lex()) == '{' || IS_TYPE_ARRAY(obj->type))) { - insert_cb(CInit_AutoObject(obj, obj->type, obj->qual)); - return; - } else { - expr = conv_assignment_expression(); - } - expr = CExpr_AssignmentPromotion(expr, obj->type, obj->qual & (Q_CONST | Q_VOLATILE), 1); - insert_cb(makediadicnode(create_objectnode2(obj), expr, EASS)); - } else if (copts.cplusplus && is_const_object(obj)) { - CError_Error(CErrorStr224); - } - - return; - } - - CInit_SetupInitInfo(&initinfo, obj); - initinfo.obj1C = obj; - initinfo.insert_expr_cb = insert_cb; - initinfo.register_object_cb = register_cb; - - if (IS_TYPE_CLASS(obj->type) && CInit_ConstructAutoObject(TYPE_CLASS(obj->type), NULL, 0, 1)) { - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 1)) { - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (tk != '=' && (tk != '(' || !copts.cplusplus)) { - if (IS_TYPE_ARRAY(obj->type)) { - type = obj->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type)) { - if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) { - CInit_InitializeClassArray(obj, TYPE_CLASS(type), 0); - CInit_CleanupInitInfo(&initinfo); - return; - } - CFunc_CheckClassCtors(TYPE_CLASS(type)); - } - } - - if (IS_TYPE_CLASS(obj->type)) - CFunc_CheckClassCtors(TYPE_CLASS(obj->type)); - - if ((IS_TYPE_REFERENCE(obj->type) || is_const_object(obj)) && copts.cplusplus) - CError_Error(CErrorStr224); - } else { - if (obj->type->size || IS_TYPE_ARRAY(obj->type)) { - if ((expr = CInit_GenericData(NULL, obj->type, obj->qual, CInit_AutoInit, 0))) - insert_cb(makediadicnode(create_objectnode2(obj), expr, EASS)); - } else { - CError_Error(CErrorStr145); - } - } - - if (IS_TYPE_CLASS(obj->type) && CClass_Destructor(TYPE_CLASS(obj->type))) - register_cb(obj->type, obj, 0, 0); - - CInit_CleanupInitInfo(&initinfo); -} - -void CInit_InitializeStaticData(Object *obj, InitExprRegisterCB cb) { - ENode *expr; - Type *type; - InitInfo initinfo; - CInit_Stuff s; - CInit_1C *entry; - ENode *obj_expr; - - if (CInit_IsSimpleStructArrayInit(obj->type)) { - if (tk == '=' || (tk == '(' && copts.cplusplus)) { - if (tk == '=') - tk = lex(); - CInit_InitData(&s, obj->type, obj->qual, copts.cplusplus); - - IsCompleteType(obj->type); - - if (!s.x1C && is_const_object(obj)) - CInit_DeclareReadOnlyData(obj, s.buffer, s.list, s.size); - else - CInit_DeclareData(obj, s.buffer, s.list, s.size); - - if (s.x1C) { - obj_expr = create_objectrefnode(obj); - entry = s.x1C; - expr = NULL; - while (entry) { - expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr); - entry = entry->next; - } - cb(expr); - } - } else { - if (copts.cplusplus && is_const_object(obj)) - CError_Error(CErrorStr224); - - if (is_const_object(obj)) - CInit_DeclareReadOnlyData(obj, NULL, NULL, obj->type->size); - else - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - return; - } - - CInit_SetupInitInfo(&initinfo, obj); - initinfo.x16 = 1; - initinfo.init_expr_register_cb = cb; - - if (IS_TYPE_CLASS(obj->type) && CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 1)) { - IsCompleteType(obj->type); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 0)) { - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (tk != '=' && (tk != '(' || !copts.cplusplus)) { - if (IsCompleteType(obj->type)) - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - - if (IS_TYPE_ARRAY(obj->type)) { - type = obj->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type)) { - if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) { - CInit_InitializeClassArray(obj, TYPE_CLASS(type), 1); - CInit_CleanupInitInfo(&initinfo); - return; - } - CFunc_CheckClassCtors(TYPE_CLASS(type)); - } - } - - if (IS_TYPE_CLASS(obj->type)) - CFunc_CheckClassCtors(TYPE_CLASS(obj->type)); - - if ((IS_TYPE_REFERENCE(obj->type) || is_const_object(obj)) && copts.cplusplus) - CError_Error(CErrorStr224); - } else { - if (obj->type->size || IS_TYPE_ARRAY(obj->type)) { - if ((expr = CInit_GenericData(obj, obj->type, obj->qual, CInit_GlobalStaticInit, 1))) - cb(makediadicnode(create_objectnode2(obj), expr, EASS)); - } else { - CError_Error(CErrorStr145); - } - } - - CInit_CleanupInitInfo(&initinfo); -} - -void CInit_InitializeData(Object *obj) { - Object *dtor; - ObjectList *list; - CInt64 val; - InitInfo initinfo; - Boolean needs_construction; - Type *type; - - if (tk == ':') { - tk = lex(); - obj->datatype = DABSOLUTE; - val = CExpr_IntegralConstExpr(); - obj->u.address = CInt64_GetULong(&val); - return; - } - - if (tk != '=' && (tk != '(' || !copts.cplusplus)) { - if (obj->sclass != TK_EXTERN) { - if (!copts.cplusplus) { - if (IsCompleteType(obj->type)) { - for (list = cinit_tentative; list; list = list->next) { - if (list->object == obj) - break; - } - if (!list) { - list = galloc(sizeof(ObjectList)); - list->object = obj; - list->next = cinit_tentative; - cinit_tentative = list; - obj->qual |= Q_1000000; - } - } - } else { - if (obj->flags & OBJECT_DEFINED) - CError_Error(CErrorStr329, obj); - obj->flags = obj->flags | OBJECT_DEFINED; - - needs_construction = 0; - if (IS_TYPE_ARRAY(obj->type)) { - type = obj->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type)) { - if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) { - CInit_SetupInitInfo(&initinfo, obj); - CInit_InitializeClassArray(obj, TYPE_CLASS(type), 1); - CInit_CleanupInitInfo(&initinfo); - needs_construction = 1; - } else { - CFunc_CheckClassCtors(TYPE_CLASS(type)); - } - } - } else { - if (IS_TYPE_CLASS(obj->type)) { - if (CInit_ClassNeedsConstruction(TYPE_CLASS(obj->type))) { - CInit_SetupInitInfo(&initinfo, obj); - CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 0); - CInit_CleanupInitInfo(&initinfo); - needs_construction = 1; - } else { - CFunc_CheckClassCtors(TYPE_CLASS(obj->type)); - } - } - } - - if (!needs_construction && copts.cplusplus) { - if (IS_TYPE_REFERENCE(obj->type) || is_const_object(obj)) - CError_Error(CErrorStr224); - } - if (IsCompleteType(obj->type)) - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - } - } - return; - } - - if (obj->flags & OBJECT_DEFINED) - CError_Error(CErrorStr329, obj); - - if (CInit_IsSimpleStructArrayInit(obj->type)) { - if (tk == '=') - tk = lex(); - else - CError_Error(CErrorStr121); - CInit_GlobalObject(obj); - return; - } - - CInit_SetupInitInfo(&initinfo, obj); - if (IS_TYPE_CLASS(obj->type) && CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 1)) { - IsCompleteType(obj->type); - CInit_DeclareData(obj, NULL, NULL, obj->type->size); - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 0)) { - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (obj->type->size == 0 && !IS_TYPE_ARRAY(obj->type)) { - CError_Error(CErrorStr145); - CInit_CleanupInitInfo(&initinfo); - return; - } - - if (copts.cplusplus) - CInit_GenericData(obj, obj->type, obj->qual, &CInit_GlobalStaticInit, 0); - else - CInit_GenericData(obj, obj->type, obj->qual, NULL, 0); - - if (IS_TYPE_CLASS(obj->type) && (dtor = CClass_Destructor(TYPE_CLASS(obj->type)))) - InitExpr_Register(CInit_RegisterDtorObject(obj->type, dtor, create_objectrefnode(obj)), obj); - - CInit_CleanupInitInfo(&initinfo); -} - -Object *CInit_DeclareString(char *data, SInt32 size, Boolean ispascal, Boolean iswide) { - PooledString *str; - Object *obj; - PooledString *scan; - - if (!copts.dont_reuse_strings) { - for (scan = cinit_stringlist; scan; scan = scan->next) { - if (scan->size == size && scan->ispascal == ispascal && scan->iswide == iswide && !memcmp(scan->data, data, size)) - return scan->obj; - } - } - - obj = CParser_NewCompilerDefDataObject(); - obj->name = CParser_GetUniqueName(); - if (iswide) { - obj->type = CDecl_NewArrayType(CParser_GetWCharType(), size); - } else { - obj->type = CDecl_NewArrayType(ispascal ? TYPE(&stunsignedchar) : TYPE(&stchar), size); - } - obj->sclass = TK_STATIC; - CScope_AddGlobalObject(obj); - - if (!iswide && !ispascal && size == (strlen(data) + 1)) - obj->section = SECT_TEXT_CSTRING; - else - obj->section = SECT_CONST; - - if (copts.readonly_strings) - CInit_DeclareReadOnlyData(obj, data, NULL, obj->type->size); - else - CInit_DeclareData(obj, data, NULL, obj->type->size); - - str = galloc(sizeof(PooledString)); - str->next = cinit_stringlist; - cinit_stringlist = str; - str->obj = obj; - str->offset = 0; - str->size = size; - str->ispascal = ispascal; - str->iswide = iswide; - str->data = galloc(size); - memcpy(str->data, data, size); - - return obj; -} - -PooledString *CInit_DeclarePooledString(char *data, SInt32 size, Boolean ispascal) { - PooledString *str; - Object *obj; - PooledString *scan; - SInt32 offset; - - if (!copts.dont_reuse_strings) { - for (scan = cinit_pooledstringlist; scan; scan = scan->next) { - if (scan->size == size && scan->ispascal == ispascal && !memcmp(scan->data, data, size)) - return scan; - } - } - - if (cinit_pooledstringlist) { - obj = cinit_pooledstringlist->obj; - offset = cinit_pooledstringlist->offset + cinit_pooledstringlist->size; - } else { - obj = CInit_CreateStaticDataObject( - CDecl_NewArrayType(ispascal ? TYPE(&stunsignedchar) : TYPE(&stchar), size), - 0, GetHashNameNodeExport("@stringBase0")); - obj->section = SECT_CONST; - offset = 0; - } - - str = galloc(sizeof(PooledString)); - str->next = cinit_pooledstringlist; - cinit_pooledstringlist = str; - str->obj = obj; - str->offset = offset; - str->size = size; - str->ispascal = ispascal; - str->data = galloc(size); - memcpy(str->data, data, size); - return str; -} - -PooledString *CInit_DeclarePooledWString(char *data, SInt32 size) { - PooledString *str; - Object *obj; - PooledString *scan; - SInt32 offset; - - if (!copts.dont_reuse_strings) { - for (scan = cinit_pooledwstringlist; scan; scan = scan->next) { - if (scan->size == size && !memcmp(scan->data, data, size)) - return scan; - } - } - - if (cinit_pooledwstringlist) { - obj = cinit_pooledwstringlist->obj; - offset = cinit_pooledwstringlist->offset + cinit_pooledwstringlist->size; - } else { - obj = CInit_CreateStaticDataObject( - CDecl_NewArrayType(CParser_GetWCharType(), size), - 0, GetHashNameNodeExport("@wstringBase0")); - obj->section = SECT_CONST; - offset = 0; - } - - str = galloc(sizeof(PooledString)); - str->next = cinit_pooledwstringlist; - cinit_pooledwstringlist = str; - str->obj = obj; - str->offset = offset; - str->size = size; - str->ispascal = 0; - str->data = galloc(size); - memcpy(str->data, data, size); - return str; -} - -void CInit_RewriteString(ENode *expr, Boolean flag) { - PooledString *str; - Boolean is_wide; - - if (cparamblkptr->precompile == 1) - CError_Error(CErrorStr180); - - CError_ASSERT(4220, expr->rtype->type == TYPEPOINTER); - - is_wide = TYPE_POINTER(expr->rtype)->target->size != 1; - if (copts.poolstrings) { - if (is_wide) - str = CInit_DeclarePooledWString(expr->data.string.data, expr->data.string.size); - else - str = CInit_DeclarePooledString(expr->data.string.data, expr->data.string.size, expr->data.string.ispascal); - - if (str->offset) { - expr->type = EADD; - expr->data.diadic.right = intconstnode(TYPE(&stunsignedlong), str->offset); - expr->data.diadic.left = create_objectrefnode(str->obj); - expr->cost = 1; - } else { - expr->type = EOBJREF; - expr->data.objref = str->obj; - } - } else { - expr->type = EOBJREF; - expr->data.objref = CInit_DeclareString(expr->data.string.data, expr->data.string.size, expr->data.string.ispascal, is_wide); - } -} - -void CInit_DeclarePooledStrings(void) { - SInt32 size; - char *buffer; - PooledString *str; - - size = 0; - for (str = cinit_pooledstringlist; str; str = str->next) - size += str->size; - - if (size) { - cinit_pooledstringlist->obj->type = CDecl_NewArrayType(TYPE(&stchar), size); - buffer = galloc(size); - for (str = cinit_pooledstringlist; str; str = str->next) - memcpy(buffer + str->offset, str->data, str->size); - - if (copts.readonly_strings) - CInit_DeclareReadOnlyData(cinit_pooledstringlist->obj, buffer, NULL, size); - else - CInit_DeclareData(cinit_pooledstringlist->obj, buffer, NULL, size); - } - - size = 0; - for (str = cinit_pooledwstringlist; str; str = str->next) - size += str->size; - - if (size) { - cinit_pooledwstringlist->obj->type = CDecl_NewArrayType(CParser_GetWCharType(), size); - buffer = galloc(size); - for (str = cinit_pooledwstringlist; str; str = str->next) - memcpy(buffer + str->offset, str->data, str->size); - - if (copts.readonly_strings) - CInit_DeclareReadOnlyData(cinit_pooledwstringlist->obj, buffer, NULL, size); - else - CInit_DeclareData(cinit_pooledwstringlist->obj, buffer, NULL, size); - } -} - -static void declaredata(Object *obj, void *data, OLinkList *list, SInt32 size, Boolean is_readonly) { - OLinkList *scan; - UInt32 qual; - - qual = obj->qual; - - if (cparamblkptr->precompile == 1) { - PreComp_StaticData(obj, data, list, size); - } else { - obj->flags = obj->flags | OBJECT_DEFINED; - if (!fatalerrors) { - for (scan = list; scan; scan = scan->next) - CInline_ObjectAddrRef(scan->obj); - if (copts.filesyminfo) - CPrep_SetSourceFile(&cparser_fileoffset); - if (is_readonly) - ObjGen_DeclareReadOnlyData(obj, data, list, size); - else - ObjGen_DeclareData(obj, data, list, size); - obj->qual = qual; - } - } -} - -void CInit_DeclareData(Object *obj, void *data, OLinkList *list, SInt32 size) { - declaredata(obj, data, list, size, 0); -} - -void CInit_DeclareReadOnlyData(Object *obj, void *data, OLinkList *list, SInt32 size) { - declaredata(obj, data, list, size, 1); -} - -void CInit_DefineTentativeData(void) { - ObjectList *list; - - for (list = cinit_tentative; list; list = list->next) { - if (!(list->object->flags & OBJECT_DEFINED)) - CInit_DeclareData(list->object, NULL, NULL, list->object->type->size); - } - - cinit_tentative = NULL; -} |