diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CABI.c')
-rw-r--r-- | compiler_and_linker/unsorted/CABI.c | 2033 |
1 files changed, 0 insertions, 2033 deletions
diff --git a/compiler_and_linker/unsorted/CABI.c b/compiler_and_linker/unsorted/CABI.c deleted file mode 100644 index 2a88de1..0000000 --- a/compiler_and_linker/unsorted/CABI.c +++ /dev/null @@ -1,2033 +0,0 @@ -#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/CFunc.h" -#include "compiler/CInit.h" -#include "compiler/CInline.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CScope.h" -#include "compiler/CSOM.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/types.h" - -typedef struct OffsetList { - struct OffsetList *next; - SInt32 offset; -} OffsetList; - -static OffsetList *trans_vtboffsets; -static BClassList cabi_pathroot; -static BClassList *cabi_pathcur; -static TypeClass *cabi_loop_class; -static Boolean cabi_loop_construct; - -short CABI_GetStructResultArgumentIndex(TypeFunc *tfunc) { - return 0; -} - -Type *CABI_GetSizeTType(void) { - return TYPE(&stunsignedlong); -} - -Type *CABI_GetPtrDiffTType(void) { - return TYPE(&stsignedlong); -} - -SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) { - SInt16 align = CMach_GetTypeAlign(type); - if (align <= 1) - return 0; - else - return (align - 1) & (align - ((size & (align - 1)))); -} - -void CABI_ReverseBitField(TypeBitfield *tbitfield) { - UInt8 bits; - UInt8 a; - UInt8 b; - - switch (tbitfield->bitfieldtype->size) { - case 1: - bits = 8; - break; - case 2: - bits = 16; - break; - case 4: - bits = 32; - break; - case 8: - bits = 64; - break; - default: - CError_FATAL(172); - } - - b = tbitfield->bitlength; - a = tbitfield->offset; - tbitfield->offset = (bits - a) - b; -} - -static void CABI_AllocateZeroVTablePointer(void *unk, TypeClass *tclass) { - ClassList *base; - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual && base->base->vtable) - return; - } - - tclass->size += void_ptr.size; -} - -static SInt32 CABI_GetBaseSize(TypeClass *tclass) { - SInt32 size = tclass->size; - - if (copts.vbase_abi_v2 && tclass->vbases) - return tclass->vbases->offset; - - return size; -} - -static void CABI_AllocateBases(ClassLayout *layout, TypeClass *tclass) { - Boolean flag; - TypeClass *baseclass; - ClassList *base; - VClassList *vbase; - SInt32 size; - - flag = 0; - size = tclass->size; - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual) { - baseclass = base->base; - if (!(baseclass->flags & CLASS_EMPTY)) { - base->offset = size + CMach_MemberAlignValue(TYPE(baseclass), size); - if (copts.vbase_abi_v2) { - size = base->offset + CABI_GetBaseSize(baseclass); - } else { - size = base->offset + baseclass->size; - for (vbase = baseclass->vbases; vbase; vbase = vbase->next) - size -= vbase->base->size; - } - flag = 0; - } else { - if (flag) - base->offset = ++size; - else - base->offset = size; - flag = 1; - } - } - } - - tclass->size = size; -} - -static void CABI_AllocateVirtualBasePointers(ClassLayout *layout, TypeClass *tclass) { - ClassList *base; - SInt32 size; - - size = tclass->size; - - for (base = tclass->bases; base; base = base->next) { - if (base->is_virtual) { - base->offset = size + CMach_MemberAlignValue(TYPE(&void_ptr), size); - size = base->offset + void_ptr.size; - } - } - - tclass->size = size; -} - -static SInt32 CABI_GetMemberOffset(TypeClass *tclass, HashNameNode *name) { - ObjMemberVar *ivar; - - if (!name) - return 0; - - ivar = tclass->ivars; - while (1) { - if (ivar->name == name) - return ivar->offset; - - if (!(ivar = ivar->next)) - CError_FATAL(362); - } -} - -static void CABI_AllocateMembers(ClassLayout *layout, TypeClass *tclass) { - ObjMemberVar *ivar; - SInt32 initialSize; - SInt32 maxSize; - TypeClass *unionClass; - SInt32 unionStart; - Boolean inAnonUnion; - Boolean removeNoNameIvars; - - removeNoNameIvars = 0; - initialSize = maxSize = tclass->size; - CMach_StructLayoutInitOffset(maxSize); - - unionClass = NULL; - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - if (!ivar->anonunion) { - if (!(ivar->offset & 0x80000000)) { - if (tclass->mode == CLASS_MODE_UNION) - CMach_StructLayoutInitOffset(initialSize); - - if (IS_TYPE_BITFIELD(ivar->type)) - ivar->offset = CMach_StructLayoutBitfield(TYPE_BITFIELD(ivar->type), ivar->qual); - else - ivar->offset = CMach_StructLayoutGetOffset(ivar->type, ivar->qual); - - if (tclass->mode == CLASS_MODE_UNION) { - SInt32 tmp = CMach_StructLayoutGetCurSize(); - if (tmp > maxSize) - maxSize = tmp; - } - - unionClass = NULL; - } else { - CError_ASSERT(412, unionClass); - ivar->offset = unionStart + CABI_GetMemberOffset(unionClass, ivar->name); - if (!inAnonUnion) - ivar->anonunion = 1; - inAnonUnion = 0; - } - - if (ivar->name == no_name_node || ivar->name == NULL) - removeNoNameIvars = 1; - } else { - CError_ASSERT(422, IS_TYPE_CLASS(ivar->type)); - - if (tclass->mode == CLASS_MODE_UNION) - CMach_StructLayoutInitOffset(initialSize); - - unionStart = CMach_StructLayoutGetOffset(ivar->type, ivar->qual); - unionClass = TYPE_CLASS(ivar->type); - inAnonUnion = 1; - - if (tclass->mode == CLASS_MODE_UNION) { - SInt32 tmp = CMach_StructLayoutGetCurSize(); - if (tmp > maxSize) - maxSize = tmp; - } - - removeNoNameIvars = 1; - } - - if (layout->vtable_ivar == ivar) - tclass->vtable->offset = ivar->offset; - } - - if (removeNoNameIvars) { - ObjMemberVar **ptr = &tclass->ivars; - while (*ptr) { - if ((*ptr)->name == NULL || (*ptr)->name == no_name_node) - *ptr = (*ptr)->next; - else - ptr = &(*ptr)->next; - } - } - - if (tclass->mode == CLASS_MODE_UNION) - tclass->size = maxSize; - else - tclass->size = CMach_StructLayoutGetCurSize(); - - if (copts.reverse_bitfields) { - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - if (IS_TYPE_BITFIELD(ivar->type)) - CABI_ReverseBitField(TYPE_BITFIELD(ivar->type)); - } - } -} - -static void CABI_AllocateVirtualBases(ClassLayout *layout, TypeClass *tclass) { - VClassList *vbase; - SInt32 size; - - size = tclass->size; - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - vbase->offset = size + CMach_MemberAlignValue(TYPE(vbase->base), size); - size = vbase->offset + CABI_GetBaseSize(vbase->base); - - if (vbase->has_override) - size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size) + 4; - } - - tclass->size = size; -} - -static Boolean CABI_FindZeroDeltaVPtr(TypeClass *tclass) { - ClassList *base; - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual && base->base->vtable && !base->offset) { - tclass->vtable->offset = base->base->vtable->offset; - return 1; - } - } - - return 0; -} - -static Object *CABI_FindZeroVirtualBaseMember(TypeClass *tclass, Object *obj) { - NameSpaceObjectList *nsol; - ClassList *base; - Object *chk; - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual && !base->offset && !base->voffset && base->base->vtable) { - for (nsol = CScope_FindName(base->base->nspace, obj->name); nsol; nsol = nsol->next) { - chk = OBJECT(nsol->object); - if ( - chk->otype == OT_OBJECT && - chk->datatype == DVFUNC && - CClass_GetOverrideKind(TYPE_FUNC(chk->type), TYPE_FUNC(obj->type), 0) == 1 - ) - return chk; - } - - if ((chk = CABI_FindZeroVirtualBaseMember(base->base, obj))) - return chk; - } - } - - return NULL; -} - -void CABI_AddVTable(TypeClass *tclass) { - tclass->vtable = galloc(sizeof(VTable)); - memclrw(tclass->vtable, sizeof(VTable)); -} - -SInt32 CABI_GetVTableOffset(TypeClass *tclass) { - return 0; -} - -static SInt32 CABI_GetBaseVTableSize(TypeClass *tclass) { - VClassList *vbase; - SInt32 size; - - size = tclass->vtable->size; - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - if (vbase->base->vtable) - size -= CABI_GetBaseVTableSize(vbase->base); - } - - return size; -} - -static void CABI_ApplyClassFlags(Object *obj, UInt8 flags, Boolean unused) { - if (flags & CLASS_EFLAGS_INTERNAL) - obj->flags = obj->flags | OBJECT_INTERNAL; - if (flags & CLASS_EFLAGS_IMPORT) - obj->flags = obj->flags | OBJECT_IMPORT; - if (flags & CLASS_EFLAGS_EXPORT) - obj->flags = obj->flags | OBJECT_EXPORT; -} - -static void CABI_AllocateVTable(ClassLayout *layout, TypeClass *tclass) { - SInt32 size; - ObjBase *objbase; - Object *obj; - ObjMemberVar *ivar; - ClassList *base; - VClassList *vbase; - int i; - - size = 0; - - if (!tclass->vtable) { - CABI_AddVTable(tclass); - layout->xA = layout->lex_order_count - 1; - } - - if (!CABI_FindZeroDeltaVPtr(tclass)) { - ivar = galloc(sizeof(ObjMemberVar)); - memclrw(ivar, sizeof(ObjMemberVar)); - - ivar->otype = OT_MEMBERVAR; - ivar->access = ACCESSPUBLIC; - ivar->name = vptr_name_node; - ivar->type = TYPE(&void_ptr); - layout->vtable_ivar = ivar; - - for (i = layout->xA; ; i--) { - if (i < 0) { - ivar->next = tclass->ivars; - tclass->ivars = ivar; - break; - } - - CError_ASSERT(666, layout->objlist[i]); - - if (layout->objlist[i]->otype == OT_MEMBERVAR) { - ivar->next = OBJ_MEMBER_VAR(layout->objlist[i])->next; - OBJ_MEMBER_VAR(layout->objlist[i])->next = ivar; - break; - } - } - - if (tclass->flags & (CLASS_SINGLE_OBJECT | CLASS_COM_OBJECT)) - size = void_ptr.size; - else - size = 8; - } else { - layout->vtable_ivar = NULL; - } - - for (base = tclass->bases; base; base = base->next) { - if (base->base->vtable && !base->is_virtual) { - base->voffset = size; - if (copts.vbase_abi_v2) { - size += CABI_GetBaseVTableSize(base->base); - } else { - size += base->base->vtable->size; - for (vbase = base->base->vbases; vbase; vbase = vbase->next) { - if (vbase->base->vtable) - size -= vbase->base->vtable->size; - } - } - } - } - - for (i = 0; i < layout->lex_order_count; i++) { - CError_ASSERT(714, objbase = layout->objlist[i]); - - if (objbase->otype == OT_OBJECT && OBJECT(objbase)->datatype == DVFUNC) { - TypeMemberFunc *tmethod = TYPE_METHOD(OBJECT(objbase)->type); - Object *baseobj = CABI_FindZeroVirtualBaseMember(tclass, OBJECT(objbase)); - - if (baseobj) { - tmethod->vtbl_index = TYPE_METHOD(baseobj->type)->vtbl_index; - } else { - tmethod->vtbl_index = size; - size += 4; - } - } - } - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - if (vbase->base->vtable) { - vbase->voffset = size; - if (copts.vbase_abi_v2) - size += CABI_GetBaseVTableSize(vbase->base); - else - size += vbase->base->vtable->size; - } - } - - obj = CParser_NewCompilerDefDataObject(); - CABI_ApplyClassFlags(obj, tclass->eflags, 0); - - obj->name = CMangler_VTableName(tclass); - obj->type = CDecl_NewStructType(size, 4); - obj->qual = Q_CONST; - obj->nspace = tclass->nspace; - switch (tclass->action) { - case CLASS_ACTION_0: - obj->sclass = TK_STATIC; - obj->qual |= Q_20000; - break; - } - - CParser_UpdateObject(obj, NULL); - - tclass->vtable->object = obj; - tclass->vtable->owner = tclass; - tclass->vtable->size = size; -} - -void CABI_LayoutClass(ClassLayout *layout, TypeClass *tclass) { - char saveAlignMode = copts.structalignment; - - tclass->size = 0; - if (!tclass->sominfo) { - if (tclass->bases) - CABI_AllocateBases(layout, tclass); - if (tclass->flags & CLASS_HAS_VBASES) - CABI_AllocateVirtualBasePointers(layout, tclass); - if (layout->has_vtable) - CABI_AllocateVTable(layout, tclass); - CABI_AllocateMembers(layout, tclass); - if (tclass->flags & CLASS_HAS_VBASES) - CABI_AllocateVirtualBases(layout, tclass); - } else { - copts.structalignment = AlignMode2_PPC; - CABI_AllocateMembers(layout, tclass); - } - - tclass->align = CMach_GetClassAlign(tclass); - if (tclass->size == 0) { - tclass->size = 1; - tclass->flags = tclass->flags | CLASS_EMPTY; - } else { - tclass->size += CABI_StructSizeAlignValue(TYPE(tclass), tclass->size); - } - - tclass->flags = tclass->flags | CLASS_COMPLETED; - - copts.structalignment = saveAlignMode; -} - -void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *func) { - DefArgCtorInfo *info; - Boolean saveDebugInfo; - ENodeList *copied; - ENodeList *argexprs; - FuncArg *args; - CScopeSave savedScope; - Statement firstStmt; - Statement returnStmt; - - CError_FATAL(860); - - if (anyerrors || func->access == ACCESSNONE) - return; - - CError_ASSERT(866, info = func->u.func.defargdata); - - CABI_ApplyClassFlags(func, tclass->eflags, 0); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - if (tclass->flags & CLASS_HAS_VBASES) - arguments->next->object->name = no_name_node; - - firstStmt.next = &returnStmt; - - memclrw(&returnStmt, sizeof(Statement)); - returnStmt.type = ST_RETURN; - returnStmt.expr = lalloc(sizeof(ENode)); - returnStmt.expr->type = EFUNCCALL; - returnStmt.expr->cost = 200; - returnStmt.expr->flags = 0; - returnStmt.expr->rtype = TYPE(&void_ptr); - - returnStmt.expr->data.funccall.funcref = CExpr_MakeObjRefNode(info->default_func, 0); - returnStmt.expr->data.funccall.functype = TYPE_FUNC(info->default_func->type); - args = TYPE_FUNC(info->default_func->type)->args; - returnStmt.expr->data.funccall.args = lalloc(sizeof(ENodeList)); - argexprs = returnStmt.expr->data.funccall.args; - - argexprs->node = create_objectnode(arguments->object); - - if (tclass->flags & CLASS_HAS_VBASES) { - args = args->next; - argexprs->next = lalloc(sizeof(ENodeList)); - argexprs = argexprs->next; - argexprs->node = create_objectnode(arguments->next->object); - } - - args = args->next; - argexprs->next = lalloc(sizeof(ENodeList)); - argexprs = argexprs->next; - argexprs->node = CInline_CopyExpression(info->default_arg, CopyMode0); - - while ((args = args->next) && args->dexpr) { - argexprs->next = lalloc(sizeof(ENodeList)); - argexprs = argexprs->next; - argexprs->node = CInline_CopyExpression(args->dexpr, CopyMode0); - } - - argexprs->next = NULL; - - CFunc_CodeCleanup(&firstStmt); - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; - - func->u.func.defargdata = NULL; -} - -static Object *CABI_ThisArg(void) { - CError_ASSERT(931, arguments && IS_TYPE_POINTER_ONLY(arguments->object->type)); - return arguments->object; -} - -ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) { - ENode *expr; - - if (tclass) { - if (!tclass->sominfo) { - expr = create_objectnode(CABI_ThisArg()); - if (tclass->flags & CLASS_HANDLEOBJECT) - expr = makemonadicnode(expr, EINDIRECT); - } else { - expr = CSOM_SOMSelfObjectExpr(tclass); - } - } else { - expr = create_objectnode(CABI_ThisArg()); - expr->rtype = TYPE(&void_ptr); - } - - if (offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); - - return expr; -} - -static Object *CABI_VArg(void) { - CError_ASSERT(976, arguments && arguments->next && IS_TYPE_INT(arguments->next->object->type)); - return arguments->next->object; -} - -static ENode *CABI_MakeVArgExpr(void) { - return create_objectnode(CABI_VArg()); -} - -static ENode *CABI_MakeCopyConArgExpr(TypeClass *tclass, Boolean flag) { - ObjectList *args; - - CError_ASSERT(1000, args = arguments); - CError_ASSERT(1001, args = args->next); - if (flag && (tclass->flags & CLASS_HAS_VBASES)) - CError_ASSERT(1002, args = args->next); - CError_ASSERT(1003, IS_TYPE_POINTER_ONLY(args->object->type)); - - return create_objectnode(args->object); -} - -static ENode *CABI_InitVBasePtr1(ENode *expr, TypeClass *tclass1, TypeClass *tclass2, TypeClass *tclass3, SInt32 offset) { - ClassList *base; - SInt32 newOffset; - OffsetList *list; - - for (base = tclass2->bases; base; base = base->next) { - if (base->base == tclass3 && base->is_virtual) { - newOffset = offset + base->offset; - - for (list = trans_vtboffsets; list; list = list->next) { - if (newOffset == list->offset) - break; - } - - if (!list) { - list = lalloc(sizeof(OffsetList)); - list->offset = newOffset; - list->next = trans_vtboffsets; - trans_vtboffsets = list; - - expr = makediadicnode( - makemonadicnode(CABI_MakeThisExpr(NULL, newOffset), EINDIRECT), - expr, - EASS); - } - } - - if (base->is_virtual) - newOffset = CClass_VirtualBaseOffset(tclass1, base->base); - else - newOffset = offset + base->offset; - - expr = CABI_InitVBasePtr1(expr, tclass1, base->base, tclass3, newOffset); - } - - return expr; -} - -static Statement *CABI_InitVBasePtrs(Statement *stmt, TypeClass *tclass) { - ENode *expr; - VClassList *vbase; - - for (vbase = tclass->vbases, trans_vtboffsets = NULL; vbase; vbase = vbase->next) { - expr = CABI_InitVBasePtr1(CABI_MakeThisExpr(NULL, vbase->offset), tclass, tclass, vbase->base, 0); - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - } - - return stmt; -} - -static OffsetList *CABI_GetVBasePath(TypeClass *tclass, TypeClass *baseclass) { - ClassList *base; - OffsetList *best; - OffsetList *list; - OffsetList *scan; - short bestLength; - short length; - - for (base = tclass->bases; base; base = base->next) { - if (base->base == baseclass && base->is_virtual) { - best = lalloc(sizeof(OffsetList)); - best->next = NULL; - best->offset = base->offset; - return best; - } - } - - best = NULL; - - for (base = tclass->bases; base; base = base->next) { - if ((list = CABI_GetVBasePath(base->base, baseclass))) { - for (scan = list->next, length = 1; scan; scan = scan->next) - length++; - - if (base->is_virtual) - length++; - - if (!best || length < bestLength) { - if (base->is_virtual) { - best = lalloc(sizeof(OffsetList)); - best->next = list; - best->offset = base->offset; - } else { - best = list; - best->offset += base->offset; - } - bestLength = length; - } - } - } - - return best; -} - -static ENode *CABI_GetVBasePtr(TypeClass *tclass, TypeClass *baseclass) { - OffsetList *path; - ENode *expr; - - CError_ASSERT(1127, path = CABI_GetVBasePath(tclass, baseclass)); - - expr = makemonadicnode(CABI_MakeThisExpr(NULL, path->offset), EINDIRECT); - - while ((path = path->next)) { - if (path->offset) - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), path->offset), EADD); - expr = makemonadicnode(expr, EINDIRECT); - } - - return expr; -} - -static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *baseclass, SInt32 offset) { - ClassList *base; - SInt32 tmp; - - if (tclass == baseclass) - return offset; - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual && (tmp = CABI_FindNVBase(base->base, baseclass, offset + base->offset)) >= 0) - return tmp; - } - - return -1; -} - -SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *baseclass) { - SInt32 baseSize; - SInt32 size; - char saveAlignMode; - - size = CABI_GetBaseSize(tclass); - if (baseclass) { - baseSize = CABI_FindNVBase(tclass, baseclass, 0); - CError_ASSERT(1178, baseSize >= 0); - size -= baseSize; - } - - saveAlignMode = copts.structalignment; - if (tclass->eflags & CLASS_EFLAGS_F0) - copts.structalignment = ((tclass->eflags & CLASS_EFLAGS_F0) >> 4) - 1; - size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size); - copts.structalignment = saveAlignMode; - - return size; -} - -static Statement *CABI_InitVBaseCtorOffsets(Statement *stmt, TypeClass *tclass) { - VClassList *vbase; - Object *tempObj; - ENode *expr; - ENode *vbaseptr; - SInt32 vboffset; - SInt32 ctorOffsetOffset; - - tempObj = NULL; - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - if (vbase->has_override) { - if (!tempObj) - tempObj = create_temp_object(TYPE(&void_ptr)); - - vboffset = CClass_VirtualBaseOffset(tclass, vbase->base); - ctorOffsetOffset = CABI_GetCtorOffsetOffset(vbase->base, NULL); - vbaseptr = CABI_GetVBasePtr(tclass, vbase->base); - CError_ASSERT(1215, vbaseptr); - - expr = makediadicnode(create_objectnode(tempObj), vbaseptr, EASS); - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - - expr = makediadicnode( - create_objectnode(tempObj), - intconstnode(TYPE(&stunsignedlong), ctorOffsetOffset), - EADD); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TYPE(&stunsignedlong); - expr = makediadicnode( - expr, - makediadicnode( - CABI_MakeThisExpr(NULL, vboffset), - create_objectnode(tempObj), - ESUB), - EASS); - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - } - } - - return stmt; -} - -static Statement *CABI_InitVTablePtrs(Statement *stmt, Object *vtableObj, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, SInt32 voffset) { - ClassList *base; - BClassList *orig_pathcur; - SInt32 newOffset; - SInt32 newVOffset; - OffsetList *offsetList; - SInt32 vtblOffset; - ENode *vtblExpr; - ENode *pathExpr; - BClassList path; - - if (baseclass->vtable->owner == baseclass) { - vtblOffset = offset + baseclass->vtable->offset; - for (offsetList = trans_vtboffsets; offsetList; offsetList = offsetList->next) { - if (vtblOffset == offsetList->offset) - break; - } - - if (!offsetList) { - offsetList = lalloc(sizeof(OffsetList)); - offsetList->offset = vtblOffset; - offsetList->next = trans_vtboffsets; - trans_vtboffsets = offsetList; - - vtblExpr = create_objectrefnode(vtableObj); - vtblExpr->rtype = TYPE(&void_ptr); - if ((vtblOffset = voffset + CABI_GetVTableOffset(baseclass))) - vtblExpr = makediadicnode(vtblExpr, intconstnode(TYPE(&stunsignedlong), vtblOffset), EADD); - - pathExpr = CClass_AccessPathCast(&cabi_pathroot, CABI_MakeThisExpr(tclass, 0), 0); - if (baseclass->vtable->offset && !canadd(pathExpr, baseclass->vtable->offset)) { - pathExpr = makediadicnode(pathExpr, intconstnode(TYPE(&stunsignedlong), baseclass->vtable->offset), EADD); - optimizecomm(pathExpr); - } - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = makediadicnode(makemonadicnode(pathExpr, EINDIRECT), vtblExpr, EASS); - } - } - - for (base = baseclass->bases; base; base = base->next) { - if (base->base->vtable) { - orig_pathcur = cabi_pathcur; - - cabi_pathcur->next = &path; - path.next = NULL; - path.type = TYPE(base->base); - cabi_pathcur = &path; - - if (base->is_virtual) { - newOffset = CClass_VirtualBaseOffset(tclass, base->base); - newVOffset = CClass_VirtualBaseVTableOffset(tclass, base->base); - } else { - newOffset = offset + base->offset; - newVOffset = voffset + base->voffset; - } - - stmt = CABI_InitVTablePtrs(stmt, vtableObj, tclass, base->base, newOffset, newVOffset); - - cabi_pathcur = orig_pathcur; - } - } - - return stmt; -} - -static Boolean CABI_IsOperatorNew(ObjBase *obj) { - return - obj->otype == OT_OBJECT && - IS_TYPE_FUNC(OBJECT(obj)->type) && - TYPE_FUNC(OBJECT(obj)->type)->args && - TYPE_FUNC(OBJECT(obj)->type)->args->type == CABI_GetSizeTType() && - !TYPE_FUNC(OBJECT(obj)->type)->args->next; -} - -Object *CABI_ConstructorCallsNew(TypeClass *tclass) { - NameSpaceObjectList *nsol; - NameResult pr; - - if (!tclass->sominfo && (tclass->flags & CLASS_HANDLEOBJECT)) { - if (CScope_FindClassMemberObject(tclass, &pr, CMangler_OperatorName(TK_NEW))) { - if (pr.obj_10) { - if (CABI_IsOperatorNew(pr.obj_10)) - return OBJECT(pr.obj_10); - } else { - for (nsol = pr.nsol_14; nsol; nsol = nsol->next) { - if (CABI_IsOperatorNew(nsol->object)) - return OBJECT(nsol->object); - } - } - } - - return newh_func; - } - - return NULL; -} - -void CABI_TransConstructor(Object *obj, Statement *firstStmt, TypeClass *tclass, TransConstructorCallback callback, Boolean has_try) { - Statement *stmt; - Object *tmpfunc; - Object *tmpfunc2; - CLabel *label; - ENode *expr; - ClassList *base; - VClassList *vbase; - ObjMemberVar *ivar; - Type *type; - CtorChain *chain; - Boolean errorflag; - - stmt = firstStmt; - - if ((tmpfunc = CABI_ConstructorCallsNew(tclass))) { - label = newlabel(); - - stmt = CFunc_InsertStatement(ST_IFGOTO, firstStmt); - stmt->expr = CABI_MakeThisExpr(NULL, 0); - stmt->label = label; - - expr = makediadicnode( - CABI_MakeThisExpr(NULL, 0), - funccallexpr(tmpfunc, intconstnode(CABI_GetSizeTType(), tclass->size), NULL, NULL, NULL), - EASS); - stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); - stmt->expr = expr; - stmt->label = label; - - stmt = CFunc_InsertStatement(ST_RETURN, stmt); - stmt->expr = NULL; - - stmt = CFunc_InsertStatement(ST_LABEL, stmt); - stmt->label = label; - label->stmt = stmt; - } - - if (has_try) { - for (stmt = firstStmt; ; stmt = stmt->next) { - CError_ASSERT(1408, stmt); - if (stmt->type == ST_BEGINCATCH) - break; - } - } - - if (!tclass->sominfo) { - if (tclass->flags & CLASS_HAS_VBASES) { - label = newlabel(); - - stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); - stmt->expr = CExpr_New_EEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0)); - stmt->label = label; - - stmt = CABI_InitVBasePtrs(stmt, tclass); - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - if (!callback) { - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_VBase && chain->u.vbase == vbase) - break; - } - - if (chain) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = chain->objexpr; - } else { - expr = CClass_DefaultConstructorCall( - vbase->base, - tclass, - CABI_MakeThisExpr(NULL, vbase->offset), - 0, 1, 1, &errorflag); - if (expr) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - } else if (errorflag) { - CError_Error(CErrorStr213, tclass, 0, vbase->base, 0); - } - } - } else { - stmt = callback(stmt, tclass, vbase->base, vbase->offset, 1); - } - - if ((tmpfunc = CClass_Destructor(vbase->base))) - CExcept_RegisterMember(stmt, CABI_ThisArg(), vbase->offset, tmpfunc, CABI_VArg(), 0); - } - - stmt = CFunc_InsertStatement(ST_LABEL, stmt); - stmt->label = label; - label->stmt = stmt; - } - - for (base = tclass->bases; base; base = base->next) { - if (base->is_virtual) - continue; - - if (!callback) { - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_Base && chain->u.base == base) - break; - } - - if (chain) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = chain->objexpr; - } else { - expr = CClass_DefaultConstructorCall( - base->base, - tclass, - CABI_MakeThisExpr(NULL, base->offset), - 0, 1, 0, &errorflag); - if (expr) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - } else if (errorflag) { - CError_Error(CErrorStr213, tclass, 0, base->base, 0); - } - } - } else { - stmt = callback(stmt, tclass, base->base, base->offset, 1); - } - - if ((tmpfunc = CClass_Destructor(base->base))) - CExcept_RegisterMember(stmt, CABI_ThisArg(), base->offset, tmpfunc, NULL, 0); - } - - if (tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) { - cabi_pathroot.next = NULL; - cabi_pathroot.type = TYPE(tclass); - cabi_pathcur = &cabi_pathroot; - trans_vtboffsets = NULL; - - stmt = CABI_InitVTablePtrs(stmt, tclass->vtable->object, tclass, tclass, 0, 0); - } - } - - if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000)) - stmt = CABI_InitVBaseCtorOffsets(stmt, tclass); - - if (!callback) { - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - for (chain = ctor_chain; chain; chain = chain->next) { - if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar) { - if (IS_TYPE_ARRAY(ivar->type)) - chain = NULL; - break; - } - } - - if (chain) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = chain->objexpr; - type = ivar->type; - switch (type->type) { - case TYPEARRAY: - do { - type = TPTR_TARGET(type); - } while (IS_TYPE_ARRAY(type)); - if (IS_TYPE_CLASS(type)) { - if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { - CError_ASSERT(1560, type->size); - CExcept_RegisterMemberArray( - stmt, - CABI_ThisArg(), - ivar->offset, - tmpfunc, - ivar->type->size / type->size, - type->size); - } - } - break; - case TYPECLASS: - if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { - CExcept_RegisterMember( - stmt, - CABI_ThisArg(), - ivar->offset, - tmpfunc, - NULL, - 1); - } - break; - } - } else { - type = ivar->type; - switch (type->type) { - case TYPEARRAY: - do { - type = TPTR_TARGET(type); - } while (IS_TYPE_ARRAY(type)); - if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type))) { - if ( - (tmpfunc = CClass_DefaultConstructor(TYPE_CLASS(type))) || - (tmpfunc = CClass_DummyDefaultConstructor(TYPE_CLASS(type))) - ) - { - tmpfunc2 = CClass_Destructor(TYPE_CLASS(type)); - if (tmpfunc2) - tmpfunc2 = CABI_GetDestructorObject(tmpfunc2, 1); - - stmt = CInit_ConstructClassArray( - stmt, - TYPE_CLASS(type), - tmpfunc, - tmpfunc2, - CABI_MakeThisExpr(tclass, ivar->offset), - ivar->type->size / type->size); - - if (tmpfunc2) - CExcept_RegisterMemberArray( - stmt, - CABI_ThisArg(), - ivar->offset, - tmpfunc2, - ivar->type->size / type->size, - type->size); - } else { - CError_Error(CErrorStr214, tclass, 0, ivar->name->name); - } - } - break; - case TYPECLASS: - expr = CClass_DefaultConstructorCall( - TYPE_CLASS(type), - NULL, - CABI_MakeThisExpr(tclass, ivar->offset), - 1, 1, 0, &errorflag); - if (expr) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = expr; - } else if (errorflag) { - CError_Error(CErrorStr214, tclass, 0, ivar->name->name); - } - - if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { - if (!expr) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = nullnode(); - } - CExcept_RegisterMember( - stmt, - CABI_ThisArg(), - ivar->offset, - tmpfunc, - NULL, - 1); - } - break; - } - } - } - } else { - stmt = callback(stmt, tclass, NULL, 0, 1); - } - - if (!tclass->sominfo) { - for (stmt = firstStmt->next; stmt; stmt = stmt->next) { - if (stmt->type == ST_RETURN) { - CError_ASSERT(1661, !stmt->expr); - stmt->expr = CABI_MakeThisExpr(NULL, 0); - } - } - } -} - -void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *func) { - Boolean saveDebugInfo; - CScopeSave savedScope; - Statement firstStmt; - Statement returnStmt; - - if (anyerrors || func->access == ACCESSNONE) - return; - - CABI_ApplyClassFlags(func, tclass->eflags, 0); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - ctor_chain = NULL; - if (tclass->flags & CLASS_HAS_VBASES) - arguments->next->object->name = CParser_GetUniqueName(); - - firstStmt.next = &returnStmt; - - memclrw(&returnStmt, sizeof(Statement)); - returnStmt.type = ST_RETURN; - - CABI_TransConstructor(func, &firstStmt, tclass, NULL, 0); - - CFunc_CodeCleanup(&firstStmt); - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; -} - -static ENode *CABI_AssignObject(TypeClass *tclass, ENode *expr1, ENode *expr2) { - Object *assignfunc; - FuncArg *arg; - - assignfunc = CClass_AssignmentOperator(tclass); - if (!assignfunc) { - expr1 = makemonadicnode(expr1, EINDIRECT); - expr1->rtype = TYPE(tclass); - return makediadicnode(expr1, expr2, EASS); - } - - CError_ASSERT(1731, - IS_TYPE_FUNC(assignfunc->type) && - (arg = TYPE_FUNC(assignfunc->type)->args) && - (arg = arg->next)); - - expr2 = argumentpromotion(expr2, arg->type, arg->qual, 1); - return funccallexpr(assignfunc, expr1, expr2, NULL, NULL); -} - -static Type *CABI_FindIntegralSizeType(SInt32 size) { - if (stunsignedchar.size == size) - return TYPE(&stunsignedchar); - if (stunsignedshort.size == size) - return TYPE(&stunsignedshort); - if (stunsignedint.size == size) - return TYPE(&stunsignedint); - if (stunsignedlong.size == size) - return TYPE(&stunsignedlong); - if (stunsignedlonglong.size == size) - return TYPE(&stunsignedlonglong); - - CError_FATAL(1756); - return NULL; -} - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct CopyRegion { - struct CopyRegion *next; - Type *type; - SInt32 start; - SInt32 end; - Boolean flag; -} CopyRegion; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -static CopyRegion *CABI_AppendCopyRegion(CopyRegion *regions, Type *type, SInt32 start, Boolean flag) { - CopyRegion *region; - SInt32 end; - - if (IS_TYPE_BITFIELD(type)) - type = TYPE_BITFIELD(type)->bitfieldtype; - - end = start + type->size; - - if (flag) { - for (region = regions; region; region = region->next) { - if (region->flag) { - if (region->start <= start && region->end >= end) - return regions; - - if (region->start >= start && region->end <= end) { - region->type = type; - region->start = start; - region->end = end; - for (region = region->next; region; region = region->next) { - if (region->start >= start && region->end <= end) - region->end = region->start; - } - return regions; - } - } - } - } - - if (regions) { - region = regions; - while (region->next) - region = region->next; - - region->next = lalloc(sizeof(CopyRegion)); - region = region->next; - } else { - regions = lalloc(sizeof(CopyRegion)); - region = regions; - } - - region->next = NULL; - region->type = type; - region->start = start; - region->end = end; - region->flag = flag; - - return regions; -} - -static ENode *CABI_ClassInitLoopCallBack(ENode *var1, ENode *var2) { - ENodeList *list; - - var2 = makemonadicnode(var2, EINDIRECT); - var2->rtype = TYPE(cabi_loop_class); - - if (cabi_loop_construct) { - list = lalloc(sizeof(ENodeList)); - memclrw(list, sizeof(ENodeList)); - list->node = var2; - return CExpr_ConstructObject(cabi_loop_class, var1, list, 1, 1, 0, 1, 1); - } else { - return CABI_AssignObject(cabi_loop_class, var1, var2); - } -} - -static Statement *CABI_CopyConAssignCB(Statement *stmt, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, Boolean flag) { - ENode *expr; - ENode *expr2; - ENode *startExpr; - ENode *endExpr; - ENodeList *list; - ObjMemberVar *ivar; - CopyRegion *regions; - Type *type; - SInt32 i; - SInt32 count; - Boolean isFlagNotSet; - Object *tmpfunc; - - if (baseclass) { - if (baseclass->flags & CLASS_EMPTY) { - if ( - (flag && !CClass_CopyConstructor(baseclass)) || - (!flag && !CClass_AssignmentOperator(baseclass)) - ) - return stmt; - } - - expr = CABI_MakeCopyConArgExpr(tclass, flag); - expr->rtype = TYPE(baseclass); - expr->data.monadic = CClass_DirectBasePointerCast(expr->data.monadic, tclass, baseclass); - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - if (flag) { - list = lalloc(sizeof(ENodeList)); - list->next = NULL; - list->node = expr; - - stmt->expr = CExpr_ConstructObject( - baseclass, - CABI_MakeThisExpr(NULL, offset), - list, - 1, 0, 0, 0, 1); - } else { - stmt->expr = CABI_AssignObject( - baseclass, - CClass_DirectBasePointerCast(CABI_MakeThisExpr(NULL, 0), tclass, baseclass), - expr); - } - } else { - isFlagNotSet = !flag; - for (ivar = tclass->ivars, regions = NULL; ivar; ivar = ivar->next) { - if (ivar->name == vptr_name_node) - continue; - - type = ivar->type; - if (isFlagNotSet) { - if (CParser_IsConst(type, ivar->qual) || IS_TYPE_REFERENCE(type) != 0) { - CError_Error(CErrorStr387, tclass, 0); - isFlagNotSet = 0; - } - } - - switch (type->type) { - case TYPEARRAY: - while (IS_TYPE_ARRAY(type)) - type = TPTR_TARGET(type); - if (!IS_TYPE_CLASS(type)) { - regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1); - break; - } - case TYPECLASS: - if (flag) { - if (CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_CopyConstructor(TYPE_CLASS(type))) { - regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0); - break; - } - } else { - if (CClass_AssignmentOperator(TYPE_CLASS(type))) { - regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0); - break; - } - } - default: - regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1); - } - } - - for (; regions; regions = regions->next) { - if (regions->start >= regions->end) - continue; - - type = regions->type; - expr = CABI_MakeCopyConArgExpr(tclass, flag); - expr->rtype = type; - - if (!canadd(expr->data.monadic, regions->start)) { - expr->data.monadic = makediadicnode( - expr->data.monadic, - intconstnode(TYPE(&stunsignedlong), regions->start), - EADD); - optimizecomm(expr->data.monadic); - } - - if (!regions->flag) { - if (IS_TYPE_ARRAY(type)) { - while (IS_TYPE_ARRAY(type)) - type = TPTR_TARGET(type); - - CError_ASSERT(1966, IS_TYPE_CLASS(type)); - - if (type->size) { - count = regions->type->size / type->size; - if (count > 4) { - startExpr = CABI_MakeThisExpr(tclass, regions->start); - endExpr = CABI_MakeThisExpr(tclass, regions->start + regions->type->size); - expr = CABI_MakeCopyConArgExpr(tclass, flag)->data.monadic; - if (!canadd(expr, regions->start)) { - expr = makediadicnode( - expr, - intconstnode(TYPE(&stunsignedlong), regions->start), - EADD); - optimizecomm(expr); - } - - cabi_loop_class = TYPE_CLASS(type); - cabi_loop_construct = flag; - stmt = CFunc_GenerateLoop( - stmt, - CDecl_NewPointerType(type), - startExpr, - endExpr, - intconstnode(TYPE(&stunsignedlong), type->size), - expr, - CABI_ClassInitLoopCallBack); - } else { - for (i = 0, offset = regions->start; i < count; i++, offset += type->size) { - expr = CABI_MakeCopyConArgExpr(tclass, flag); - expr->rtype = type; - - if (!canadd(expr->data.monadic, offset)) { - expr->data.monadic = makediadicnode( - expr->data.monadic, - intconstnode(TYPE(&stunsignedlong), offset), - EADD); - optimizecomm(expr->data.monadic); - } - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - if (flag) { - list = lalloc(sizeof(ENodeList)); - memclrw(list, sizeof(ENodeList)); - list->node = expr; - stmt->expr = CExpr_ConstructObject( - TYPE_CLASS(type), - CABI_MakeThisExpr(tclass, offset), - list, - 1, 1, 0, 1, 1); - } else { - stmt->expr = CABI_AssignObject( - TYPE_CLASS(type), - CABI_MakeThisExpr(tclass, offset), - expr); - } - } - } - - if (flag && (tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) - CExcept_RegisterMemberArray(stmt, CABI_ThisArg(), regions->start, tmpfunc, count, type->size); - } - } else { - CError_ASSERT(2027, IS_TYPE_CLASS(type)); - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - - if (flag) { - list = lalloc(sizeof(ENodeList)); - memclrw(list, sizeof(ENodeList)); - list->node = expr; - stmt->expr = CExpr_ConstructObject( - TYPE_CLASS(type), - CABI_MakeThisExpr(tclass, regions->start), - list, - 1, 1, 0, 1, 1); - - if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) - CExcept_RegisterMember(stmt, CABI_ThisArg(), regions->start, tmpfunc, NULL, 1); - } else { - stmt->expr = CABI_AssignObject( - TYPE_CLASS(type), - CABI_MakeThisExpr(tclass, regions->start), - expr); - } - } - } else { - if (IS_TYPE_ARRAY(type)) { - if (type->size > 1 && ((regions->start & 1) || (type->size & 1))) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = funccallexpr( - copy_func, - CABI_MakeThisExpr(tclass, regions->start), - getnodeaddress(expr, 0), - intconstnode(CABI_GetSizeTType(), type->size), - NULL); - continue; - } - - type = CDecl_NewStructType(type->size, CMach_GetTypeAlign(type)); - expr->rtype = type; - } - - expr2 = makemonadicnode(CABI_MakeThisExpr(tclass, regions->start), EINDIRECT); - expr2->rtype = type; - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = makediadicnode(expr2, expr, EASS); - } - } - } - - return stmt; -} - -void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *func) { - Boolean saveDebugInfo; - CScopeSave savedScope; - Statement firstStmt; - Statement returnStmt; - - if (anyerrors || func->access == ACCESSNONE) - return; - - CABI_ApplyClassFlags(func, tclass->eflags, 0); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - ctor_chain = NULL; - if (tclass->flags & CLASS_HAS_VBASES) - arguments->next->object->name = CParser_GetUniqueName(); - - firstStmt.next = &returnStmt; - - memclrw(&returnStmt, sizeof(Statement)); - returnStmt.type = ST_RETURN; - - CABI_TransConstructor(func, &firstStmt, tclass, CABI_CopyConAssignCB, 0); - - CFunc_CodeCleanup(&firstStmt); - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; -} - -void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *func) { - Boolean saveDebugInfo; - Statement *stmt; - ClassList *base; - VClassList *vbase; - ENode *expr1; - ENode *expr2; - CScopeSave savedScope; - Statement firstStmt; - - if (anyerrors || func->access == ACCESSNONE) - return; - - CABI_ApplyClassFlags(func, tclass->eflags, 0); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - stmt = curstmt; - - if (tclass->mode == CLASS_MODE_UNION) { - expr1 = makemonadicnode(CABI_MakeThisExpr(tclass, 0), EINDIRECT); - expr1->rtype = TYPE(tclass); - - expr2 = CABI_MakeCopyConArgExpr(tclass, 0); - expr2->rtype = TYPE(tclass); - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = makediadicnode(expr1, expr2, EASS); - } else { - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - stmt = CABI_CopyConAssignCB(stmt, tclass, vbase->base, vbase->offset, 0); - } - - for (base = tclass->bases; base; base = base->next) { - if (!base->is_virtual) - stmt = CABI_CopyConAssignCB(stmt, tclass, base->base, base->offset, 0); - } - - stmt = CABI_CopyConAssignCB(stmt, tclass, NULL, 0, 0); - } - - stmt = CFunc_InsertStatement(ST_RETURN, stmt); - stmt->expr = CABI_MakeThisExpr(NULL, 0); - - CFunc_CodeCleanup(&firstStmt); - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; -} - -static Statement *CABI_DestroyMembers(Statement *stmt, ObjMemberVar *ivars, TypeClass *tclass) { - Type *type; - Object *dtor; - ENode *expr; - - for (; ivars; ivars = ivars->next) { - type = ivars->type; - - if (IS_TYPE_ARRAY(type)) { - while (IS_TYPE_ARRAY(type)) - type = TPTR_TARGET(type); - - if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) { - dtor = CABI_GetDestructorObject(dtor, 1); - stmt = CABI_DestroyMembers(stmt, ivars->next, tclass); - expr = create_objectrefnode(dtor); - expr->flags = expr->flags | ENODE_FLAG_80; - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = funccallexpr( - darr_func, - CABI_MakeThisExpr(tclass, ivars->offset), - expr, - intconstnode(TYPE(&stsignedlong), type->size), - intconstnode(TYPE(&stsignedlong), ivars->type->size / type->size) - ); - return stmt; - } - } else { - if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) { - stmt = CABI_DestroyMembers(stmt, ivars->next, tclass); - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = CABI_DestroyObject( - dtor, - CABI_MakeThisExpr(tclass, ivars->offset), - CABIDestroy1, - 1, - 0 - ); - return stmt; - } - } - } - - return stmt; -} - -static Statement *CABI_DestroyBases(Statement *stmt, ClassList *bases) { - ClassList *base; - Object *dtor; - SInt32 count; - SInt32 i; - - base = bases; - count = 0; - while (base) { - base = base->next; - count++; - } - - while (count > 0) { - base = bases; - i = count; - while (i-- > 1) - base = base->next; - - if (!base->is_virtual && (dtor = CClass_Destructor(base->base))) { - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = CABI_DestroyObject( - dtor, - CABI_MakeThisExpr(NULL, base->offset), - CABIDestroy0, - 1, - 0); - } - - count--; - } - - return stmt; -} - -static Statement *CABI_DestroyVBases(Statement *stmt, VClassList *vbases) { - Object *dtor; - - for (; vbases; vbases = vbases->next) { - if ((dtor = CClass_Destructor(vbases->base))) { - stmt = CABI_DestroyVBases(stmt, vbases->next); - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = CABI_DestroyObject( - dtor, - CABI_MakeThisExpr(NULL, vbases->offset), - CABIDestroy0, - 1, - 0); - break; - } - } - - return stmt; -} - -void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass, CABIDestroyMode mode) { - CLabel *label2; - Boolean flag29; - CLabel *label; - Statement *scan; - Boolean flag25; - Boolean flag24; - Boolean flag23; - CLabel *label3; - Object *dealloc; - Boolean deallocFlag; - - if (tclass->sominfo) { - flag24 = 0; - flag25 = 0; - flag29 = 0; - flag23 = 1; - } else { - flag24 = 1; - flag23 = 1; - flag25 = 1; - flag29 = 1; - } - - label = newlabel(); - - for (scan = stmt; scan; scan = scan->next) { - if (scan->type == ST_RETURN) { - CError_ASSERT(2329, !scan->expr); - scan->type = ST_GOTO; - scan->label = label; - } - - if (scan->next && scan->next->type == ST_RETURN && !scan->next->next) { - CError_ASSERT(2334, !scan->next->expr); - scan->next = NULL; - break; - } - } - - scan = stmt; - - if (flag29) { - label2 = newlabel(); - scan = CFunc_InsertStatement(ST_IFNGOTO, scan); - scan->expr = CABI_MakeThisExpr(NULL, 0); - scan->label = label2; - } - - if (flag25 && tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) { - cabi_pathroot.next = NULL; - cabi_pathroot.type = TYPE(tclass); - cabi_pathcur = &cabi_pathroot; - trans_vtboffsets = NULL; - scan = CABI_InitVTablePtrs(scan, tclass->vtable->object, tclass, tclass, 0, 0); - } - - if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000)) - CABI_InitVBaseCtorOffsets(scan, tclass); - - scan = stmt; - while (scan->next) - scan = scan->next; - - scan = CFunc_InsertStatement(ST_LABEL, scan); - scan->label = label; - scan->dobjstack = NULL; - label->stmt = scan; - - if (flag23 && !(tclass->flags & CLASS_HANDLEOBJECT)) - scan = CABI_DestroyMembers(scan, tclass->ivars, tclass); - - if (flag25 && tclass->bases) - scan = CABI_DestroyBases(scan, tclass->bases); - - if (flag24 && (tclass->flags & CLASS_HAS_VBASES)) { - label3 = newlabel(); - scan = CFunc_InsertStatement(ST_IFNGOTO, scan); - scan->expr = CABI_MakeVArgExpr(); - scan->label = label3; - - scan = CABI_DestroyVBases(scan, tclass->vbases); - - scan = CFunc_InsertStatement(ST_LABEL, scan); - scan->label = label3; - label3->stmt = scan; - } - - if (flag29) { - scan = CFunc_InsertStatement(ST_IFGOTO, scan); - scan->expr = CExpr_New_ELESSEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0)); - scan->label = label2; - - scan = CFunc_InsertStatement(ST_EXPRESSION, scan); - dealloc = CParser_FindDeallocationObject(TYPE(tclass), NULL, 0, 0, &deallocFlag); - if (deallocFlag) { - scan->expr = funccallexpr( - dealloc, - CABI_MakeThisExpr(NULL, 0), - intconstnode(CABI_GetSizeTType(), tclass->size), - NULL, - NULL); - } else { - scan->expr = funccallexpr(dealloc, CABI_MakeThisExpr(NULL, 0), NULL, NULL, NULL); - } - - scan = CFunc_InsertStatement(ST_LABEL, scan); - scan->label = label2; - label2->stmt = scan; - } - - scan = CFunc_InsertStatement(ST_RETURN, scan); - if (tclass->sominfo) - scan->expr = NULL; - else - scan->expr = CABI_MakeThisExpr(NULL, 0); -} - -void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *func) { - Boolean saveDebugInfo; - CScopeSave savedScope; - Statement firstStmt; - Statement returnStmt; - - if (anyerrors || func->access == ACCESSNONE) - return; - - CABI_ApplyClassFlags(func, tclass->eflags, 0); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - firstStmt.next = &returnStmt; - - memclrw(&returnStmt, sizeof(Statement)); - returnStmt.type = ST_RETURN; - - CFunc_CodeCleanup(&firstStmt); - - CABI_TransDestructor(func, func, &firstStmt, tclass, CABIDestroy0); - - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; -} - -static void CABI_CreateLayeredDestructor(TypeClass *tclass, Object *obj1, Object *func, CABIDestroyMode mode) { - Boolean saveDebugInfo; - CScopeSave savedScope; - Statement firstStmt; - Statement returnStmt; - - CError_FATAL(2524); - - CScope_SetFunctionScope(func, &savedScope); - - CFunc_FuncGenSetup(&firstStmt, func); - - saveDebugInfo = copts.filesyminfo; - copts.filesyminfo = 0; - - CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); - - firstStmt.next = &returnStmt; - - memclrw(&returnStmt, sizeof(Statement)); - returnStmt.type = ST_RETURN; - - CFunc_CodeCleanup(&firstStmt); - - CABI_TransDestructor(obj1, func, &firstStmt, tclass, mode); - - CFunc_Gen(&firstStmt, func, 0); - - CScope_RestoreScope(&savedScope); - copts.filesyminfo = saveDebugInfo; -} - -void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *func) { - Object *dtor; - CABIDestroyMode mode; - - CError_FATAL(2557); - - if (anyerrors || func->access == ACCESSNONE) - return; - - if ((dtor = CClass_Destructor(tclass))) { - if (CABI_GetDestructorObject(dtor, CABIDestroy0) == func) - mode = CABIDestroy0; - else if (CABI_GetDestructorObject(dtor, CABIDestroy2) == func) - mode = CABIDestroy2; - else if (CABI_GetDestructorObject(dtor, CABIDestroy3) == func) - mode = CABIDestroy3; - else if (CABI_GetDestructorObject(dtor, CABIDestroy1) == func) - mode = CABIDestroy1; - else - CError_FATAL(2567); - } - - CABI_CreateLayeredDestructor(tclass, dtor, func, mode); -} - -Object *CABI_GetDestructorObject(Object *obj, CABIDestroyMode mode) { - return obj; -} - -static void CABI_AddLayeredDestructor(TypeClass *tclass, Object *dtor, HashNameNode *name, Boolean is_virtual) { - Object *func; - - CError_FATAL(2667); - - func = CParser_NewFunctionObject(NULL); - func->nspace = dtor->nspace; - func->name = name; - func->type = TYPE(CDecl_MakeDefaultDtorType(tclass, is_virtual)); - func->qual = Q_20000 | Q_MANGLE_NAME; - func->qual |= Q_INLINE; - CABI_ApplyClassFlags(func, tclass->eflags, 1); - - CError_ASSERT(2678, IS_TYPE_FUNC(func->type)); - TYPE_FUNC(func->type)->flags |= FUNC_AUTO_GENERATED; - - if (dtor->datatype == DVFUNC) { - func->datatype = DVFUNC; - CMangler_GetLinkName(func); - func->datatype = DFUNC; - } - - CScope_AddObject(func->nspace, func->name, OBJ_BASE(func)); -} - -void CABI_AddLayeredDestructors(TypeClass *tclass) { - Object *dtor; - - CError_FATAL(2707); - - if ((dtor = CClass_Destructor(tclass))) { - CABI_AddLayeredDestructor(tclass, dtor, CMangler_DeleteDtorName(), 1); - CABI_AddLayeredDestructor(tclass, dtor, CMangler_SDeleteDtorName(), 1); - if (tclass->vbases) - CABI_AddLayeredDestructor(tclass, dtor, CMangler_VBaseDtorName(), 0); - } -} - -ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, CABIDestroyMode mode, Boolean flag1, Boolean flag2) { - ENode *expr; - short arg; - ENodeList *list; - - switch (mode) { - case CABIDestroy2: - case CABIDestroy3: - if (flag2) - arg = 1; - else - arg = -1; - break; - case CABIDestroy1: - arg = -1; - break; - case CABIDestroy0: - arg = 0; - break; - default: - CError_FATAL(2786); - } - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 200; - expr->flags = 0; - expr->rtype = &stvoid; - expr->data.funccall.funcref = create_objectrefnode(dtor); - if (flag1) - expr->data.funccall.funcref->flags = expr->data.funccall.funcref->flags | ENODE_FLAG_80; - expr->data.funccall.functype = TYPE_FUNC(dtor->type); - dtor->flags = dtor->flags | OBJECT_USED; - - list = lalloc(sizeof(ENodeList)); - list->node = objexpr; - expr->data.funccall.args = list; - - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->next = NULL; - list->node = intconstnode(TYPE(&stsignedshort), arg); - - return expr; -} |