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