summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/unsorted/CInit.c')
-rw-r--r--compiler_and_linker/unsorted/CInit.c3082
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;
-}