summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CClass.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/unsorted/CClass.c')
-rw-r--r--compiler_and_linker/unsorted/CClass.c2312
1 files changed, 0 insertions, 2312 deletions
diff --git a/compiler_and_linker/unsorted/CClass.c b/compiler_and_linker/unsorted/CClass.c
deleted file mode 100644
index fad276e..0000000
--- a/compiler_and_linker/unsorted/CClass.c
+++ /dev/null
@@ -1,2312 +0,0 @@
-#include "compiler/CClass.h"
-#include "compiler/CABI.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CParser.h"
-#include "compiler/CRTTI.h"
-#include "compiler/CSOM.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct OVClassBase {
- struct OVClassBase *next;
- struct OVClass *ovclass;
- Boolean is_virtual;
-} OVClassBase;
-
-typedef struct OVFunc {
- struct OVFunc *next;
- Object *obj;
- struct OVClass *ovc8;
- struct OVFunc *ovfC;
- struct OVFunc *ovf10;
-} OVFunc;
-
-typedef struct OVClass {
- TypeClass *tclass;
- OVFunc *vfuncs;
- OVClassBase *bases;
- SInt32 offset;
- SInt32 voffset;
- Boolean alloced_vtable;
-} OVClass;
-
-typedef struct ThunkList {
- struct ThunkList *next;
- Object *thunkobj;
- Object *obj;
- SInt32 a;
- SInt32 b;
- SInt32 c;
-} ThunkList;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static TypeClass *main_class;
-static ThunkList *cclass_thunklist;
-static TypeClass *cclass_isbase_mostderived;
-static SInt32 cclass_isbase_foundoffset;
-static Boolean cclass_isambigbase;
-static short cclass_founddepth;
-static char *vtable_object_data;
-static SInt32 vtable_data_size;
-static OLinkList *vtable_object_links;
-static TypeClass *cclass_vbase;
-static OVClass *cclass_ovbase;
-static OVClass *cclass_root;
-static Object *found_pure;
-static Boolean check_pures;
-static Object *cclass_dominator_vobject;
-static SInt32 cclass_dominator_voffset;
-static Object *cclass_dominator_oobject;
-static TypeClass *cclass_dominator_oclass;
-static SInt32 cclass_dominator_ooffset;
-static Object *cclass_dominator_eobject;
-
-void CClass_Init(void) {
- cclass_thunklist = NULL;
-}
-
-void CClass_GenThunks(void) {
- ThunkList *list;
-
- for (list = cclass_thunklist; list; list = list->next) {
- list->thunkobj->flags |= OBJECT_DEFINED;
- CodeGen_GenVDispatchThunk(list->thunkobj, list->obj, list->a, list->b, list->c);
- }
-}
-
-static Object *CClass_ThunkObject(Object *obj, SInt32 a, SInt32 b, SInt32 c) {
- Object *thunkobj;
- ThunkList *list;
-
- CInline_ObjectAddrRef(obj);
- for (list = cclass_thunklist; list; list = list->next) {
- if (obj == list->obj && a == list->a && b == list->b && c == list->c)
- return list->thunkobj;
- }
-
- thunkobj = CParser_NewCompilerDefFunctionObject();
- thunkobj->name = CMangler_ThunkName(obj, a, b, c);
- thunkobj->type = TYPE(&rt_func);
- thunkobj->sclass = TK_EXTERN;
- thunkobj->qual = Q_20000;
- thunkobj->u.func.linkname = thunkobj->name;
-
- list = galloc(sizeof(ThunkList));
- list->thunkobj = thunkobj;
- list->obj = obj;
- list->a = a;
- list->b = b;
- list->c = c;
- list->next = cclass_thunklist;
- cclass_thunklist = list;
-
- return thunkobj;
-}
-
-static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) {
- while (1) {
- if (a == b)
- return 1;
-
- if (!a->bases || a->bases->is_virtual)
- return 0;
-
- a = a->bases->base;
- }
-}
-
-static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB, Boolean errorflag) {
- TypeClass *tclassA;
- TypeClass *tclassB;
-
- if (
- IS_TYPE_POINTER_ONLY(a) &&
- IS_TYPE_POINTER_ONLY(b) &&
- TPTR_QUAL(a) == TPTR_QUAL(b) &&
- !CParser_IsMoreCVQualified(qualB, qualA) &&
- IS_TYPE_CLASS(TPTR_TARGET(a)) &&
- IS_TYPE_CLASS(TPTR_TARGET(b))
- )
- {
- tclassA = TYPE_CLASS(TPTR_TARGET(a));
- tclassB = TYPE_CLASS(TPTR_TARGET(b));
- if (tclassA == tclassB || CClass_IsBaseClass(tclassB, tclassA, NULL, errorflag, errorflag)) {
- if (!CClass_IsZeroOffsetClass(tclassB, tclassA))
- return 2;
- else
- return 1;
- }
- }
-
- return 0;
-}
-
-UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) {
- if (!a->args || !b->args)
- return 0;
-
- if (
- (a->flags & FUNC_CALL_CONV_MASK) != (b->flags & FUNC_CALL_CONV_MASK) ||
- !is_arglistsame(a->args->next, b->args->next) ||
- a->args->qual != b->args->qual
- )
- return 0;
-
- if (!is_typesame(a->functype, b->functype)) {
- switch (CClass_IsCovariantResult(a->functype, a->qual, b->functype, b->qual, errorflag)) {
- case 0:
- if (errorflag)
- CError_Error(CErrorStr227);
- return 0;
- case 1:
- return 1;
- case 2:
- return 2;
- default:
- CError_FATAL(225);
- }
- }
-
- return 1;
-}
-
-Boolean CClass_IsEmpty(TypeClass *tclass) {
- ClassList *base;
-
- if (tclass->ivars)
- return 0;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!CClass_IsEmpty(base->base))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_IsNonStaticMemberFunc(TypeFunc *tfunc) {
- return IS_TYPEFUNC_NONSTATIC_METHOD(tfunc) || (tfunc->flags & FUNC_FLAGS_80);
-}
-
-Object *CClass_DefaultConstructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- if (TYPE_FUNC(object->type)->args->next && !TYPE_FUNC(object->type)->args->next->next)
- return object;
- } else {
- if (!TYPE_FUNC(object->type)->args->next)
- return object;
- }
- }
- }
-
- return NULL;
-}
-
-Object *CClass_DummyDefaultConstructor(TypeClass *tclass) {
- Object *ctor;
- FuncArg *args;
- NameSpaceObjectList *nsol;
- HashNameNode *name;
- TypeMemberFunc *tmethod;
- Object *object;
- ObjectList list;
-
- ctor = NULL;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(305, args = TYPE_FUNC(object->type)->args);
- args = args->next;
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- CError_ASSERT(309, args);
- args = args->next;
- }
- CError_ASSERT(312, args);
-
- if (args->dexpr) {
- if (ctor) {
- list.next = NULL;
- list.object = object;
- CError_OverloadedFunctionError(ctor, &list);
- break;
- }
- ctor = object;
- }
- }
- }
-
- if (!ctor) {
- CError_Error(CErrorStr203);
- return NULL;
- }
-
- name = GetHashNameNodeExport("__defctor");
- if ((nsol = CScope_FindName(tclass->nspace, name))) {
- CError_ASSERT(339, nsol->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(nsol->object)->type));
- return OBJECT(nsol->object);
- }
-
- tmethod = galloc(sizeof(TypeMemberFunc));
- memclrw(tmethod, sizeof(TypeMemberFunc));
-
- tmethod->type = TYPEFUNC;
- tmethod->functype = TYPE(&void_ptr);
- tmethod->flags = FUNC_METHOD;
- tmethod->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmethod), 0);
-
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo)
- CDecl_AddArgument(TYPE_FUNC(tmethod), TYPE(&stsignedshort));
-
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmethod), tclass);
-
- object = CParser_NewCompilerDefFunctionObject();
- object->type = TYPE(tmethod);
- object->qual = Q_INLINE | Q_MANGLE_NAME;
- object->nspace = tclass->nspace;
- object->name = name;
-
- CScope_AddObject(tclass->nspace, name, OBJ_BASE(object));
- CParser_RegisterDummyCtorFunction(object, ctor);
- return object;
-}
-
-ENode *CClass_DefaultConstructorCall(TypeClass *tclass, TypeClass *b, ENode *objexpr, SInt32 varg, Boolean flag1, Boolean flag2, Boolean *errorflag) {
- NameSpaceObjectList *nsol;
- Object *ctor;
- Object *object;
- FuncArg *args;
- ENodeList *argexprs;
- ENode *expr;
- BClassList *path;
- BClassList list1;
- ObjectList objlist;
- BClassList list2;
- short founddepth;
- Boolean isambigbase;
-
- *errorflag = 0;
-
- if (!(nsol = CScope_FindName(tclass->nspace, constructor_name_node)))
- return NULL;
-
- ctor = NULL;
- do {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(397, args = TYPE_FUNC(object->type)->args);
-
- args = args->next;
-
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- CError_ASSERT(401, args);
- args = args->next;
- }
-
- if (!args || args->dexpr) {
- if (ctor) {
- objlist.next = NULL;
- objlist.object = object;
- CError_OverloadedFunctionError(ctor, &objlist);
- break;
- }
- ctor = object;
- }
- }
- } while ((nsol = nsol->next));
-
- if (!ctor) {
- *errorflag = 1;
- return NULL;
- }
-
- if (flag1) {
- if (b) {
- if (flag2) {
- if ((path = CClass_GetBasePath(b, tclass, &founddepth, &isambigbase)))
- list1 = *path;
- else
- goto skipCheck;
- } else {
- list1.next = &list2;
- list1.type = TYPE(b);
- list2.next = NULL;
- list2.type = TYPE(tclass);
- }
- } else {
- list1.next = NULL;
- list1.type = TYPE(tclass);
- }
- CClass_CheckPathAccess(&list1, ctor, ctor->access);
- }
-
-skipCheck:
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- argexprs = lalloc(sizeof(ENodeList));
- argexprs->next = NULL;
- argexprs->node = intconstnode(TYPE(&stsignedshort), varg);
- } else {
- argexprs = NULL;
- }
-
- CError_ASSERT(471, IS_TYPE_POINTER_ONLY(objexpr->rtype));
-
- objexpr = makemonadicnode(objexpr, EINDIRECT);
- objexpr->rtype = TYPE(tclass);
-
- list1.next = NULL;
- list1.type = TYPE(tclass);
-
- expr = CExpr_GenericFuncCall(
- &list1,
- objexpr,
- 0,
- ctor,
- NULL,
- NULL,
- argexprs,
- 0,
- 0,
- 0
- );
-
- if (ENODE_IS2(expr, EFUNCCALL, EFUNCCALLP))
- expr->rtype = CDecl_NewPointerType(TYPE(tclass));
-
- return expr;
-}
-
-Object *CClass_AssignmentOperator(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
-
- for (nsol = CScope_FindName(tclass->nspace, asop_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (
- object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(object->type) &&
- TYPE_FUNC(object->type)->args &&
- TYPE_FUNC(object->type)->args->next &&
- !TYPE_FUNC(object->type)->args->next->next
- )
- {
- if (
- IS_TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) &&
- TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) == tclass
- )
- return object;
-
- if (
- IS_TYPE_REFERENCE(TYPE_FUNC(object->type)->args->next->type) &&
- TPTR_TARGET(TYPE_FUNC(object->type)->args->next->type) == TYPE(tclass)
- )
- return object;
- }
- }
-
- return NULL;
-}
-
-Object *CClass_CopyConstructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
- FuncArg *args;
-
- if (tclass->sominfo)
- return NULL;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(532, args = TYPE_FUNC(object->type)->args);
-
- args = args->next;
-
- if (tclass->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(536, args);
- args = args->next;
- }
-
- if (
- args &&
- args != &elipsis &&
- (!args->next || args->next->dexpr) &&
- IS_TYPE_REFERENCE(args->type) &&
- TPTR_TARGET(args->type) == TYPE(tclass)
- )
- return object;
- }
- }
-
- return NULL;
-}
-
-NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) {
- NameSpaceObjectList *nsol;
-
- if ((nsol = CScope_FindName(tclass->nspace, name)) && nsol->object->otype == OT_OBJECT)
- return nsol;
-
- return NULL;
-}
-
-NameSpaceObjectList *CClass_Constructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
-
- if (
- (nsol = CScope_FindName(tclass->nspace, constructor_name_node)) &&
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type)
- )
- return nsol;
-
- return NULL;
-}
-
-Object *CClass_Destructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
-
- for (nsol = CScope_FindName(tclass->nspace, destructor_name_node); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type)
- )
- return OBJECT(nsol->object);
- }
-
- return NULL;
-}
-
-Boolean CClass_IsConstructor(Object *obj) {
- return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_CTOR);
-}
-
-Boolean CClass_IsDestructor(Object *obj) {
- return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_DTOR);
-}
-
-Boolean CClass_IsPODClass(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->bases || CClass_Destructor(tclass))
- return 0;
-
- for (nsol = CClass_Constructor(tclass); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type) &&
- !(TYPE_FUNC(OBJECT(nsol->object)->type)->flags & FUNC_AUTO_GENERATED)
- )
- return 0;
- }
-
- object = CClass_AssignmentOperator(tclass);
- if (object && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->access != ACCESSPUBLIC)
- return 0;
-
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- switch (type->type) {
- case TYPECLASS:
- if (!CClass_IsPODClass(TYPE_CLASS(type)))
- return 0;
- break;
- case TYPEMEMBERPOINTER:
- return 0;
- case TYPEPOINTER:
- if (TPTR_QUAL(type) & Q_REFERENCE)
- return 0;
- break;
- }
- }
-
- return 1;
-}
-
-Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) {
- Object *object;
- ClassList *base;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->vbases || CClass_Destructor(tclass))
- return 0;
-
- object = CClass_CopyConstructor(tclass);
- if (object && IS_TYPE_FUNC(object->type) && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!CClass_IsTrivialCopyClass(base->base))
- return 0;
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyClass(TYPE_CLASS(type)))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) {
- Object *object;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->bases || CClass_Destructor(tclass))
- return 0;
-
- object = CClass_AssignmentOperator(tclass);
- if (object && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_REFERENCE(type))
- return 0;
- if (CParser_IsConst(type, ivar->qual))
- return 0;
- if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyAssignClass(TYPE_CLASS(type)))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_ReferenceArgument(TypeClass *tclass) {
- if ((tclass->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(tclass));
-
- if (copts.simple_class_byval)
- return !CClass_IsTrivialCopyClass(tclass);
-
- return CClass_Destructor(tclass) || CClass_CopyConstructor(tclass);
-}
-
-BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) {
- BClassList *last;
- BClassList *copy;
-
- if (!path)
- return NULL;
-
- copy = last = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList));
- last->next = path->next;
- last->type = path->type;
-
- while ((path = path->next)) {
- last->next = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList));
- last = last->next;
- last->next = path->next;
- last->type = path->type;
- }
-
- return copy;
-}
-
-BClassList *CClass_AppendPath(BClassList *dest, BClassList *src) {
- BClassList *last;
-
- if (!(last = dest))
- return src;
-
- while (last->next)
- last = last->next;
-
- while (src && src->type == last->type)
- src = src->next;
-
- last->next = src;
- return dest;
-}
-
-static AccessType CClass_GetPathAccess(BClassList *path) {
- AccessType result;
- ClassList *base;
- TypeClass *tclass;
-
- CError_ASSERT(930, path);
-
- result = ACCESSPUBLIC;
-
- while (1) {
- tclass = TYPE_CLASS(path->type);
- if (!(path = path->next))
- break;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->type))
- break;
- }
-
- CError_ASSERT(939, base);
-
- switch (base->access) {
- case ACCESSPUBLIC:
- break;
- case ACCESSPROTECTED:
- if (result == ACCESSPUBLIC)
- result = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (result == ACCESSPUBLIC || result == ACCESSPROTECTED)
- result = ACCESSPRIVATE;
- else
- return ACCESSNONE;
- break;
- case ACCESSNONE:
- return ACCESSNONE;
- default:
- CError_FATAL(960);
- }
- }
-
- return result;
-}
-
-Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) {
- switch (CClass_GetPathAccess(path2)) {
- case ACCESSPUBLIC:
- return 0;
- case ACCESSNONE:
- return 1;
- default:
- CError_FATAL(978);
- case ACCESSPROTECTED:
- switch (CClass_GetPathAccess(path1)) {
- case ACCESSPUBLIC:
- return 1;
- case ACCESSPRIVATE:
- case ACCESSPROTECTED:
- case ACCESSNONE:
- return 0;
- default:
- CError_FATAL(987);
- }
- case ACCESSPRIVATE:
- switch (CClass_GetPathAccess(path1)) {
- case ACCESSPUBLIC:
- case ACCESSPROTECTED:
- return 1;
- case ACCESSPRIVATE:
- case ACCESSNONE:
- return 0;
- default:
- CError_FATAL(997);
- }
- }
-
- return 0;
-}
-
-static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) {
- ClassList *base;
- BClassList *checkpath;
- BClassList *bestpath;
- BClassList *newpath;
- SInt32 newOffset;
-
- for (base = a->bases, bestpath = NULL; base; base = base->next) {
- if (base->is_virtual)
- newOffset = CClass_VirtualBaseOffset(cclass_isbase_mostderived, base->base);
- else
- newOffset = offset + base->offset;
-
- if (base->base == b) {
- if (cclass_founddepth && newOffset != cclass_isbase_foundoffset) {
- cclass_isambigbase = 1;
- return NULL;
- }
-
- cclass_isbase_foundoffset = newOffset;
- cclass_founddepth = depth;
-
- bestpath = lalloc(sizeof(BClassList));
- bestpath->next = NULL;
- bestpath->type = TYPE(b);
- } else if ((checkpath = CClass_GetBasePathRec(base->base, b, newOffset, depth + 1))) {
- newpath = lalloc(sizeof(BClassList));
- newpath->next = checkpath;
- newpath->type = TYPE(base->base);
- if (!bestpath || CClass_IsMoreAccessiblePath(newpath, bestpath))
- bestpath = newpath;
- }
- }
-
- return bestpath;
-}
-
-BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) {
- BClassList *path;
- BClassList *result;
-
- if ((a->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(a));
- if ((b->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(b));
-
- cclass_founddepth = 0;
- cclass_isbase_mostderived = a;
- cclass_isbase_foundoffset = -1;
- cclass_isambigbase = 0;
-
- if ((path = CClass_GetBasePathRec(a, b, 0, 1))) {
- *founddepth = cclass_founddepth;
- *isambigbase = cclass_isambigbase;
-
- result = lalloc(sizeof(BClassList));
- result->next = path;
- result->type = TYPE(a);
- return result;
- } else {
- *isambigbase = 0;
- return NULL;
- }
-}
-
-Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) {
- BClassList *path;
- short depth;
- Boolean isambigbase;
-
- if ((path = CClass_GetBasePath(a, b, &depth, &isambigbase))) {
- if (isambigbase && ambigerrorflag)
- CError_Error(CErrorStr188);
-
- if (pathcheckflag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
-
- if (founddepth)
- *founddepth = depth;
-
- return 1;
- }
-
- return 0;
-}
-
-TypeClass *CClass_GetQualifiedClass(void) {
- DeclInfo di;
-
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (IS_TYPE_CLASS(di.thetype))
- return TYPE_CLASS(di.thetype);
-
- return NULL;
-}
-
-ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean reverse) {
- ClassList *base;
- SInt32 offset;
-
- while (path && path->next) {
- base = TYPE_CLASS(path->type)->bases;
- while (1) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- CError_ASSERT(1157, base = base->next);
- }
-
- if (base->is_virtual) {
- if (reverse) {
- CError_Error(CErrorStr164);
- break;
- }
-
- if (!base->base->sominfo) {
- offset = base->offset;
- if (offset && !canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
-
- expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(TYPE(base->base)));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = expr->data.monadic->rtype;
- }
- } else {
- offset = base->offset;
- if (offset) {
- if (reverse)
- offset = -offset;
- if (!canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
- }
- }
-
- path = path->next;
- }
-
- return expr;
-}
-
-ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) {
- BClassList *path;
- Boolean reverse;
- short depth;
- Boolean isambigbase;
-
- reverse = 0;
-
- if (a != b) {
- if (!(path = CClass_GetBasePath(a, b, &depth, &isambigbase))) {
- CError_ASSERT(1216, typconflag);
- if ((path = CClass_GetBasePath(b, a, &depth, &isambigbase))) {
- reverse = 1;
- goto doCast;
- }
- } else {
- doCast:
- if (isambigbase && ambigerrorflag)
- CError_Error(CErrorStr188);
- if (pathcheckflag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
- if (!(a->flags & CLASS_SINGLE_OBJECT) && !b->sominfo)
- expr = CClass_AccessPathCast(path, expr, reverse);
- }
- }
-
- if (typconflag && ENODE_IS(expr, EINDIRECT) && IS_TYPE_POINTER_ONLY(expr->rtype))
- expr = makemonadicnode(expr, ETYPCON);
-
- return expr;
-}
-
-ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) {
- ClassList *base;
- VClassList *vbase;
- BClassList *path;
- BClassList list1;
- BClassList list2;
- short depth;
- Boolean isambigbase;
-
- for (base = a->bases; base; base = base->next) {
- if (base->base == b) {
- list1.next = &list2;
- list1.type = TYPE(a);
- list2.next = NULL;
- list2.type = TYPE(b);
- return CClass_AccessPathCast(&list1, expr, 0);
- }
- }
-
- for (vbase = a->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == b) {
- CError_ASSERT(1273, path = CClass_GetBasePath(a, b, &depth, &isambigbase));
- return CClass_AccessPathCast(path, expr, 0);
- }
- }
-
- CError_FATAL(1277);
- return expr;
-}
-
-SInt32 CClass_GetPathOffset(BClassList *path) {
- SInt32 offset;
- ClassList *base;
-
- offset = 0;
-
- while (path->next) {
- if (path->type != path->next->type) {
- for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- }
-
- if (!base) {
- CError_Error(CErrorStr221);
- return offset;
- }
- }
-
- if (base->is_virtual)
- return -1;
- offset += base->offset;
-
- path = path->next;
- }
-
- return offset;
-}
-
-Boolean CClass_ClassDominates(TypeClass *tclass, TypeClass *baseclass) {
- ClassList *base;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == baseclass || CClass_ClassDominates(base->base, baseclass))
- return 1;
- }
-
- return 0;
-}
-
-SInt32 CClass_VirtualBaseOffset(TypeClass *tclass, TypeClass *baseclass) {
- VClassList *vbase;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == baseclass)
- return vbase->offset;
- }
-
- CError_FATAL(1342);
- return 0;
-}
-
-SInt32 CClass_VirtualBaseVTableOffset(TypeClass *tclass, TypeClass *baseclass) {
- VClassList *vbase;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == baseclass)
- return vbase->voffset;
- }
-
- CError_FATAL(1359);
- return 0;
-}
-
-SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **resultIvar) {
- ObjMemberVar *ivar;
- ClassList *base;
- SInt32 offset;
- SInt32 tmp;
- Boolean foundflag;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->name == name) {
- if (resultIvar)
- *resultIvar = ivar;
- return ivar->offset;
- }
- }
-
- for (base = tclass->bases, foundflag = 0; base; base = base->next) {
- switch ((tmp = CClass_GetMemberOffset(base->base, name, resultIvar))) {
- case -3:
- case -2:
- return tmp;
- case -1:
- break;
- default:
- if (base->is_virtual)
- return -3;
- if (foundflag)
- return -2;
- foundflag = 1;
- offset = base->offset + tmp;
- }
- }
-
- return foundflag ? offset : -1;
-}
-
-Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) {
- NameSpaceObjectList *nsol;
- ClassList *base;
- Boolean result;
-
- result = 0;
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable) {
- for (nsol = CScope_FindName(base->base->nspace, name); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- OBJECT(nsol->object)->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(OBJECT(nsol->object)->type), TYPE_FUNC(obj->type), 1)
- )
- result = 1;
- }
-
- if (CClass_OverridesBaseMember(base->base, name, obj))
- result = 1;
- }
- }
-
- return result;
-}
-
-static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) {
- OVClassBase *ovbase;
-
- if (ovclass->tclass == tclass && ovclass->offset == offset)
- return ovclass;
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) {
- if ((ovclass = CClass_FindOVClass(ovbase->ovclass, tclass, offset)))
- return ovclass;
- }
-
- return NULL;
-}
-
-static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) {
- ClassList *base;
- Object *object;
- OVClass *tree;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
- SInt32 vboffset;
- SInt32 vbvoffset;
- CScopeObjectIterator iter;
-
- tree = lalloc(sizeof(OVClass));
- memclrw(tree, sizeof(OVClass));
-
- tree->tclass = tclass;
- tree->offset = offset;
- tree->voffset = voffset;
- if (!root)
- root = tree;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- ovfunc = lalloc(sizeof(OVFunc));
- memclrw(ovfunc, sizeof(OVFunc));
-
- ovfunc->next = tree->vfuncs;
- ovfunc->obj = object;
- tree->vfuncs = ovfunc;
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable || base->base->sominfo) {
- ovbase = lalloc(sizeof(OVClassBase));
- memclrw(ovbase, sizeof(OVClassBase));
-
- if (base->is_virtual) {
- vboffset = CClass_VirtualBaseOffset(main_class, base->base);
- if (!(ovbase->ovclass = CClass_FindOVClass(root, base->base, vboffset))) {
- vbvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base);
- ovbase->ovclass = CClass_BuildOVClassTree(root, base->base, vboffset, vbvoffset);
- }
- ovbase->is_virtual = 1;
- } else {
- ovbase->ovclass = CClass_BuildOVClassTree(
- root,
- base->base,
- offset + base->offset,
- voffset + base->voffset);
- ovbase->is_virtual = 0;
- }
-
- ovbase->next = tree->bases;
- tree->bases = ovbase;
- }
- }
-
- return tree;
-}
-
-static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) {
- OVClassBase *ovbase;
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next) {
- if (
- (ovbase->ovclass->tclass == a->tclass && ovbase->ovclass->offset == a->offset) ||
- CClass_IsBaseOf(a, ovbase->ovclass)
- )
- {
- if (!cclass_ovbase && ovbase->is_virtual)
- cclass_ovbase = ovbase->ovclass;
- return 1;
- }
- }
-
- return 0;
-}
-
-static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) {
- OVFunc *scan;
- OVClassBase *ovbase;
- UInt8 overrideKind;
-
- if (CClass_IsBaseOf(b, a)) {
- for (scan = a->vfuncs; scan; scan = scan->next) {
- if (
- (func->obj->name == scan->obj->name) &&
- (overrideKind = CClass_GetOverrideKind(TYPE_FUNC(func->obj->type), TYPE_FUNC(scan->obj->type), 0))
- )
- {
- if (func->ovc8) {
- if (func->ovc8->tclass == a->tclass || CClass_ClassDominates(func->ovc8->tclass, a->tclass))
- return;
- if (!CClass_ClassDominates(a->tclass, func->ovc8->tclass)) {
- func->ovf10 = scan;
- return;
- }
- }
-
- if (a == cclass_root) {
- TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_20;
- if (overrideKind == 2)
- TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_400000;
- }
-
- func->ovc8 = a;
- func->ovfC = scan;
- func->ovf10 = NULL;
- return;
- }
- }
-
- for (ovbase = a->bases; ovbase; ovbase = ovbase->next)
- CClass_FindOVFunc(ovbase->ovclass, b, func);
- }
-}
-
-static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) {
- Object *object;
- TypeList *scan;
- Type *type;
- ClassList *base;
- CScopeObjectIterator iter;
-
- if (!flag) {
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- object->name == func->name &&
- object->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(object->type), TYPE_FUNC(func->type), 0) == 2
- )
- {
- CError_ASSERT(1686,
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->functype) &&
- IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(object->type)->functype)));
-
- type = TPTR_TARGET(TYPE_FUNC(object->type)->functype);
- for (scan = list; scan; scan = scan->next) {
- if (scan->type == type)
- break;
- }
-
- if (!scan) {
- scan = lalloc(sizeof(TypeList));
- scan->type = type;
- scan->next = list;
- list = scan;
- }
- }
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable)
- list = CClass_GetCoVariantClassList(list, base->base, func, 0);
- }
-
- return list;
-}
-
-static TypeMemberFunc *CClass_GetCovariantType(TypeMemberFunc *tmethod, Type *type) {
- TypePointer *tptr;
- TypeMemberFunc *result;
-
- CError_ASSERT(1724,
- IS_TYPE_METHOD(tmethod) &&
- IS_TYPE_POINTER_ONLY(tmethod->functype));
-
- tptr = galloc(sizeof(TypePointer));
- *tptr = *TYPE_POINTER(tmethod->functype);
- tptr->target = type;
-
- result = galloc(sizeof(TypeMemberFunc));
- *result = *tmethod;
- result->flags &= ~(FUNC_FLAGS_20 | FUNC_FLAGS_400000);
- result->functype = TYPE(tptr);
- return result;
-}
-
-static Object *CClass_FindCovariantFunction(Object *func, Type *type) {
- NameSpaceObjectList *nsol;
-
- nsol = CScope_FindName(
- TYPE_METHOD(func->type)->theclass->nspace,
- CMangler_GetCovariantFunctionName(func, TYPE_CLASS(type)));
-
- CError_ASSERT(1754, nsol && !nsol->next && nsol->object->otype == OT_OBJECT);
-
- return OBJECT(nsol->object);
-}
-
-static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) {
- Object *newfunc;
- HashNameNode *name;
- TypeList *types;
- ObjectList *newlist;
-
- for (types = CClass_GetCoVariantClassList(NULL, tclass, func, 1); types; types = types->next) {
- name = CMangler_GetCovariantFunctionName(func, TYPE_CLASS(types->type));
-
- newfunc = galloc(sizeof(Object));
- memclrw(newfunc, sizeof(Object));
-
- newfunc->otype = OT_OBJECT;
- newfunc->datatype = DFUNC;
- newfunc->section = func->section;
- newfunc->nspace = func->nspace;
- newfunc->name = name;
- newfunc->type = TYPE(CClass_GetCovariantType(TYPE_METHOD(func->type), types->type));
- newfunc->qual = func->qual & ~Q_INLINE;
- newfunc->sclass = func->sclass;
- newfunc->u.func.linkname = name;
-
- newlist = lalloc(sizeof(ObjectList));
- newlist->object = newfunc;
- newlist->next = list;
- list = newlist;
- }
-
- return list;
-}
-
-void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) {
- NameSpace *nspace;
- TypeList *types;
- Object *covariantFunc;
- Statement *stmt;
- Type *tptr;
- Statement firstStmt;
-
- for (types = CClass_GetCoVariantClassList(NULL, TYPE_METHOD(method->type)->theclass, method, 1); types; types = types->next) {
- covariantFunc = CClass_FindCovariantFunction(method, types->type);
- tptr = CDecl_NewPointerType(types->type);
-
- nspace = CFunc_FuncGenSetup(&firstStmt, covariantFunc);
- CInline_UnpackIFunctionData(covariantFunc, ifuncdata, &firstStmt);
-
- for (stmt = &firstStmt; stmt; stmt = stmt->next) {
- if (stmt->type == ST_RETURN && stmt->expr)
- stmt->expr = CExpr_AssignmentPromotion(stmt->expr, tptr, ENODE_QUALS(stmt->expr), 0);
- }
-
- CFunc_Gen(&firstStmt, covariantFunc, 0);
- cscope_current = nspace->parent;
- }
-}
-
-static void CClass_OverrideOVClassTree(OVClass *ovclass) {
- OVClassBase *ovbase;
- OVFunc *ovfunc;
-
- if (cclass_root != ovclass) {
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next)
- CClass_FindOVFunc(cclass_root, ovclass, ovfunc);
- }
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next)
- CClass_OverrideOVClassTree(ovbase->ovclass);
-}
-
-static void CClass_AllocVTableRec(OVClass *ovclass) {
- OVFunc *ovfunc;
- Object *object;
- SInt32 offset27;
- SInt32 offset26;
- SInt32 offset23;
- OVClassBase *ovbase;
- OLinkList *link;
-
- if (ovclass->alloced_vtable)
- return;
-
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- offset27 = ovclass->voffset + TYPE_METHOD(ovfunc->obj->type)->vtbl_index + CABI_GetVTableOffset(ovclass->tclass);
- CError_ASSERT(1867, offset27 < vtable_data_size);
-
- if (!(vtable_object_data[offset27])) {
- if (ovfunc->ovfC) {
- object = ovfunc->ovfC->obj;
- if (
- (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000) &&
- CClass_GetOverrideKind(TYPE_FUNC(ovfunc->obj->type), TYPE_FUNC(object->type), 0) == 2
- )
- {
- CError_ASSERT(1887,
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(ovfunc->obj->type)->functype) &&
- IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype)));
- object = CClass_FindCovariantFunction(
- object,
- TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype));
- }
-
- if ((offset26 = ovfunc->ovc8->offset - ovclass->offset)) {
- if (!(TYPE_FUNC(object->type)->flags & FUNC_PURE)) {
- cclass_ovbase = NULL;
- CError_ASSERT(1899, CClass_IsBaseOf(ovclass, ovfunc->ovc8));
-
- if (cclass_ovbase && (main_class->flags & CLASS_FLAGS_8000)) {
- offset23 = ovclass->offset - cclass_ovbase->offset;
- offset23 = CABI_GetCtorOffsetOffset(cclass_ovbase->tclass, NULL) - offset23;
- CError_ASSERT(1906, offset23 > 0);
- object = CClass_ThunkObject(object, offset26, 0, offset23);
- } else {
- object = CClass_ThunkObject(object, offset26, 0, -1);
- }
- }
- }
- } else {
- object = ovfunc->obj;
- }
-
- if (!(TYPE_FUNC(object->type)->flags & FUNC_PURE)) {
- link = lalloc(sizeof(OLinkList));
- link->next = vtable_object_links;
- link->obj = object;
- link->offset = offset27;
- link->somevalue = 0;
- vtable_object_links = link;
- vtable_object_data[offset27] = 1;
- }
- }
- }
-
- ovclass->alloced_vtable = 1;
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next)
- CClass_AllocVTableRec(ovbase->ovclass);
-}
-
-static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) {
- Object *object;
- Object *check;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
-
- object = NULL;
-
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovf10 && errorflag)
- CError_Error(CErrorStr251, main_class, 0, ovfunc->obj, ovfunc->ovfC->obj, ovfunc->ovf10->obj);
-
- if (!object) {
- check = ovfunc->ovfC ? ovfunc->ovfC->obj : ovfunc->obj;
- if (TYPE_FUNC(check->type)->flags & FUNC_PURE)
- object = check;
- }
- }
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) {
- if (object)
- CClass_CheckClass(ovbase->ovclass, errorflag);
- else
- object = CClass_CheckClass(ovbase->ovclass, errorflag);
- }
-
- return object;
-}
-
-static void CClass_AllocVTable(TypeClass *tclass) {
- OVClass *ovclass;
-
- main_class = tclass;
- ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = ovclass;
- CClass_OverrideOVClassTree(ovclass);
- CClass_CheckClass(ovclass, 1);
- CClass_AllocVTableRec(ovclass);
-}
-
-static Object *CClass_CheckVirtuals(TypeClass *tclass) {
- OVClass *ovclass;
-
- main_class = tclass;
- ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = ovclass;
- CClass_OverrideOVClassTree(ovclass);
- return CClass_CheckClass(ovclass, 0);
-}
-
-static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) {
- VClassList *vbase;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
-
- if (flag) {
- for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovfC) {
- cclass_ovbase = NULL;
- CError_ASSERT(2040, CClass_IsBaseOf(b, ovfunc->ovc8));
-
- if (cclass_ovbase) {
- for (vbase = a->tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == cclass_ovbase->tclass)
- break;
- }
-
- CError_ASSERT(2047, vbase);
- vbase->has_override = 1;
- }
- }
- }
- }
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next) {
- CClass_CheckVirtualBaseOverrides(a, ovbase->ovclass, flag || ovbase->is_virtual);
- }
-}
-
-static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) {
- OVClassBase *ovbase;
- OVFunc *ovfunc;
- Object *foundObject;
- Boolean isAlias;
- Object *object;
- CScopeObjectIterator iter;
-
- if (a != b) {
- for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovc8 != a) {
- foundObject = NULL;
- isAlias = 0;
- CScope_InitObjectIterator(&iter, a->tclass->nspace);
-
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->name == ovfunc->obj->name && IS_TYPE_FUNC(object->type)) {
- if (object->datatype != DALIAS) {
- if (!(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20))
- foundObject = object;
- } else {
- if (object->u.alias.object == ovfunc->obj) {
- // don't show a warning if this is just an alias to the base function
- isAlias = 1;
- break;
- }
- }
- }
- }
-
- if (foundObject && !isAlias)
- CError_Warning(CErrorStr225, foundObject, ovfunc->obj);
- }
- }
- }
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next)
- CClass_CheckHideVirtual(a, ovbase->ovclass);
-}
-
-void CClass_CheckOverrides(TypeClass *tclass) {
- OVClass *tree;
- Object *object;
- ObjectList *objlist;
- ClassList *base;
- VClassList *vbase;
- int i;
- CScopeObjectIterator iter;
-
- i = 0;
- for (base = tclass->bases; base; base = base->next) {
- base->offset = i;
- base->voffset = i;
- i++;
- }
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- vbase->offset = i;
- vbase->voffset = i;
- i++;
- }
-
- main_class = tclass;
- tree = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = tree;
-
- CClass_OverrideOVClassTree(tree);
- if (CClass_CheckClass(tree, 0))
- tclass->flags |= CLASS_ABSTRACT;
-
- if (copts.warn_hidevirtual)
- CClass_CheckHideVirtual(tree, tree);
-
- if (tclass->flags & CLASS_FLAGS_8000)
- CClass_CheckVirtualBaseOverrides(tree, tree, 0);
-
- objlist = NULL;
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- CError_ASSERT(2175, IS_TYPE_FUNC(object->type));
- if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000)
- objlist = CClass_DeclareCovariantFuncs(objlist, object, tclass);
- }
- }
-
- while (objlist) {
- CScope_AddObject(tclass->nspace, objlist->object->name, OBJ_BASE(objlist->object));
- objlist = objlist->next;
- }
-
- for (base = tclass->bases; base; base = base->next) {
- base->offset = 0;
- base->voffset = 0;
- }
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- vbase->offset = 0;
- vbase->voffset = 0;
- }
-}
-
-static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *tclass3) {
- Object *object;
- ClassList *base;
- CScopeObjectIterator iter;
-
- CScope_InitObjectIterator(&iter, tclass1->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- object->name == cclass_dominator_vobject->name &&
- object->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(cclass_dominator_vobject->type), TYPE_FUNC(object->type), 0)
- )
- {
- if (object == cclass_dominator_vobject && offset1 == cclass_dominator_voffset) {
- if (object1) {
- if (cclass_dominator_oobject && cclass_dominator_ooffset != offset2) {
- if (CClass_ClassDominates(cclass_dominator_oclass, tclass2))
- return;
- if (!CClass_ClassDominates(tclass2, cclass_dominator_oclass)) {
- cclass_dominator_eobject = object1;
- cclass_vbase = tclass3;
- return;
- }
- }
-
- cclass_dominator_oobject = object1;
- cclass_dominator_ooffset = offset2;
- cclass_dominator_oclass = tclass2;
- cclass_dominator_eobject = NULL;
- cclass_vbase = tclass3;
- }
- return;
- } else {
- if (!object1) {
- object1 = object;
- tclass2 = tclass1;
- offset2 = offset1;
- }
- break;
- }
- }
- }
-
- for (base = tclass1->bases; base; base = base->next) {
- if (base->base->vtable) {
- if (!base->is_virtual) {
- CClass_FindDominator(base->base, offset1 + base->offset, object1, tclass2, offset2, tclass3);
- } else {
- SInt32 vboffset = CClass_VirtualBaseOffset(main_class, base->base);
- CClass_FindDominator(base->base, vboffset, object1, tclass2, offset2, base->base);
- }
- }
- }
-}
-
-static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *baseclass) {
- Object *object;
- Object *thunkobject;
- SInt32 newoffset;
- SInt32 newvoffset;
- ClassList *base;
- SInt32 thunkoffset;
- OLinkList *olink;
- CScopeObjectIterator iter;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- newoffset = voffset + TYPE_METHOD(object->type)->vtbl_index + CABI_GetVTableOffset(tclass);
- CError_ASSERT(2288, newoffset < vtable_data_size);
-
- if (!vtable_object_data[newoffset]) {
- cclass_dominator_vobject = object;
- cclass_dominator_voffset = offset;
- cclass_dominator_oobject = NULL;
- cclass_dominator_ooffset = offset;
- CClass_FindDominator(main_class, 0, NULL, NULL, 0, NULL);
-
- if (cclass_dominator_oobject) {
- if (cclass_dominator_eobject)
- CError_Error(CErrorStr251, main_class, 0, cclass_dominator_vobject, cclass_dominator_oobject, cclass_dominator_eobject);
- } else {
- cclass_dominator_oobject = object;
- cclass_vbase = NULL;
- }
-
- vtable_object_data[newoffset] = 1;
-
- if (!(TYPE_FUNC(cclass_dominator_oobject->type)->flags & FUNC_PURE)) {
- if (!check_pures) {
- thunkobject = cclass_dominator_oobject;
- if ((thunkoffset = cclass_dominator_ooffset - offset)) {
- if (cclass_vbase && (main_class->flags & CLASS_FLAGS_8000)) {
- thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0,
- CABI_GetCtorOffsetOffset(cclass_vbase, tclass));
- } else {
- thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0, -1);
- }
- }
-
- olink = lalloc(sizeof(OLinkList));
- olink->next = vtable_object_links;
- olink->obj = thunkobject;
- olink->offset = newoffset;
- olink->somevalue = 0;
- vtable_object_links = olink;
- }
- } else {
- found_pure = cclass_dominator_oobject;
- }
- }
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable) {
- if (base->is_virtual) {
- newoffset = CClass_VirtualBaseOffset(main_class, base->base);
- newvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base);
- CClass_ConstructVTable(
- base->base,
- newvoffset,
- newoffset,
- base->base
- );
- } else {
- CClass_ConstructVTable(
- base->base,
- voffset + base->voffset,
- offset + base->offset,
- baseclass
- );
- }
- }
- }
-}
-
-void CClass_ClassDefaultFuncAction(TypeClass *tclass) {
-}
-
-void CClass_ClassAction(TypeClass *tclass) {
- if (tclass->sominfo) {
- CSOM_GenerateClassStructures(tclass);
- } else if (tclass->vtable) {
- vtable_data_size = tclass->vtable->size;
- vtable_object_data = lalloc(vtable_data_size);
- memclrw(vtable_object_data, vtable_data_size);
-
- main_class = tclass;
- vtable_object_links = NULL;
- found_pure = NULL;
- check_pures = 0;
-
- CClass_AllocVTable(tclass);
-
- memclrw(vtable_object_data, vtable_data_size);
- if (copts.RTTI && !(tclass->flags & (CLASS_SINGLE_OBJECT | CLASS_COM_OBJECT)))
- vtable_object_links = CRTTI_ConstructVTableHeaders(tclass, vtable_object_data, vtable_object_links);
-
- CError_ASSERT(2492, tclass->vtable->object->type->size == tclass->vtable->size);
- CInit_DeclareData(tclass->vtable->object, vtable_object_data, vtable_object_links, tclass->vtable->size);
- }
-}
-
-void CClass_MakeStaticActionClass(TypeClass *tclass) {
- if (tclass->vtable) {
- tclass->vtable->object->sclass = TK_STATIC;
- tclass->vtable->object->qual |= Q_20000;
- if (!(tclass->vtable->object->flags & OBJECT_FLAGS_2)) {
- CParser_NewCallBackAction(tclass->vtable->object, tclass);
- } else if (cparamblkptr->precompile != 1) {
- CParser_NewClassAction(tclass);
- }
- }
-}
-
-Object *CClass_CheckPures(TypeClass *tclass) {
- return CClass_CheckVirtuals(tclass);
-}
-
-void CClass_MemberDef(Object *obj, TypeClass *tclass) {
- switch (tclass->action) {
- case CLASS_ACTION_0:
- break;
- case CLASS_ACTION_1:
- if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_4)) {
- if (obj->qual & Q_INLINE) {
- if (tclass->sominfo)
- CError_Error(CErrorStr280);
- tclass->action = CLASS_ACTION_0;
- CClass_MakeStaticActionClass(tclass);
- } else if (cparamblkptr->precompile != 1) {
- CParser_NewClassAction(tclass);
- }
- }
- break;
- case CLASS_ACTION_2:
- CError_FATAL(2682);
- break;
- case CLASS_ACTION_3:
- break;
- default:
- CError_FATAL(2701);
- }
-}
-
-Object *CClass_ThisSelfObject(void) {
- ObjectList *list;
-
- if (cscope_currentfunc && cscope_currentclass) {
- if (cscope_currentclass->objcinfo) {
- for (list = arguments; list; list = list->next) {
- if (list->object->name == self_name_node)
- return list->object;
- }
- CError_Error(CErrorStr301);
- } else {
- if (cscope_is_member_func) {
- for (list = arguments; list; list = list->next) {
- if (list->object->name == this_name_node)
- return list->object;
- }
- }
- CError_Error(CErrorStr189);
- }
- }
-
- CError_Error(copts.cplusplus ? CErrorStr189 : CErrorStr301);
- return NULL;
-}
-
-ENode *CClass_CreateThisSelfExpr(void) {
- Object *object;
- ENode *expr;
-
- if (!(object = CClass_ThisSelfObject()))
- return NULL;
-
- expr = create_objectrefnode(object);
- expr->rtype = CDecl_NewPointerType(TYPE(cscope_currentclass));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
-
- return expr;
-}
-
-static AccessType CClass_BaseMemberAccess(BClassList *path, AccessType access) {
- ClassList *base;
-
- if (path->next) {
- access = CClass_BaseMemberAccess(path->next, access);
- switch (access) {
- case ACCESSPRIVATE:
- case ACCESSNONE:
- return ACCESSNONE;
- }
-
- for (base = TYPE_CLASS(path->type)->bases; ; base = base->next) {
- if (!base)
- return ACCESSNONE;
-
- if (base->base == TYPE_CLASS(path->next->type)) {
- switch (base->access) {
- case ACCESSNONE:
- access = ACCESSNONE;
- break;
- case ACCESSPROTECTED:
- if (access == ACCESSPUBLIC)
- access = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (access == ACCESSPRIVATE)
- access = ACCESSNONE;
- else
- access = ACCESSPRIVATE;
- break;
- case ACCESSPUBLIC:
- break;
- }
- break;
- }
- }
- }
-
- return access;
-}
-
-static Boolean CClass_CanAccess(BClassList *path, AccessType access) {
- AccessType access2;
- BClassList *scan;
- BClassList *next;
- TypeClass *prevclass;
- TypeClass *tclass;
- ClassList *base;
- ClassFriend *cfriend;
-
- tclass = TYPE_CLASS(path->type);
- access2 = access;
- if ((scan = path->next)) {
- if (access2 != ACCESSPRIVATE) {
- prevclass = tclass;
- while (scan) {
- for (base = prevclass->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(scan->type))
- break;
- }
-
- if (!base)
- return 0;
-
- switch (base->access) {
- case ACCESSNONE:
- access2 = ACCESSNONE;
- break;
- case ACCESSPROTECTED:
- if (access2 == ACCESSPUBLIC)
- access2 = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (access2 == ACCESSPRIVATE)
- access2 = ACCESSNONE;
- else
- access2 = ACCESSPRIVATE;
- break;
- case ACCESSPUBLIC:
- break;
- }
-
- prevclass = TYPE_CLASS(scan->type);
- scan = scan->next;
- }
- } else {
- access2 = ACCESSNONE;
- }
- }
-
- if (access2 == ACCESSPUBLIC)
- return 1;
-
- if (access2 != ACCESSNONE) {
- if (cscope_currentclass == tclass)
- return 1;
- if (cobjc_currentclass == tclass)
- return 1;
-
- for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) {
- if (cfriend->isclass) {
- if (cfriend->u.theclass == cscope_currentclass)
- return 1;
- } else {
- if (cfriend->u.obj == cscope_currentfunc)
- return 1;
- }
- }
- }
-
- for (scan = path; scan->next; scan = scan->next) {
- if (CClass_CanAccess(scan->next, access)) {
- if ((next = scan->next->next) || access != ACCESSPUBLIC) {
- scan->next->next = NULL;
- if (CClass_CanAccess(path, ACCESSPUBLIC)) {
- scan->next->next = next;
- return 1;
- }
- scan->next->next = next;
- }
- }
- }
-
- return 0;
-}
-
-void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) {
- if (!CClass_CanAccess(path, access)) {
- if (path && obj)
- CError_Error(CErrorStr381, path->type, 0, obj);
- else
- CError_Error(CErrorStr187);
- }
-}
-
-static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) {
- BClassList *first;
- ClassList *base;
-
- first = path;
-
- while (1) {
- if (!path->next) {
- if (!tclass)
- return first;
- if (path->type == TYPE(tclass))
- return first;
- return NULL;
- }
-
- if (path->type != path->next->type) {
- for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- }
-
- if (base) {
- path = path->next;
- } else {
- first = path = path->next;
- }
- } else {
- path->next = path->next->next;
- }
- }
-}
-
-void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) {
- ClassFriend *cfriend;
-
- if (path) {
- path = CClass_PathCleanup(path, tclass);
- if (path && path->next) {
- if (!CClass_CanAccess(path, access))
- CError_Error(CErrorStr187);
- return;
- }
- }
-
- switch (access) {
- case ACCESSPUBLIC:
- return;
- case ACCESSPRIVATE:
- case ACCESSPROTECTED:
- if (tclass == cscope_currentclass)
- return;
-
- for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) {
- if (cfriend->isclass) {
- if (cfriend->u.theclass == cscope_currentclass)
- return;
- } else {
- if (cfriend->u.obj == cscope_currentfunc)
- return;
- }
- }
- case ACCESSNONE:
- CError_Warning(CErrorStr187);
- return;
- default:
- CError_FATAL(3013);
- }
-}
-
-void CClass_CheckObjectAccess(BClassList *path, Object *obj) {
- short depth;
- Boolean isambigbase;
-
- if (obj->nspace && obj->nspace->theclass) {
- if (!path && cscope_currentclass)
- path = CClass_GetBasePath(cscope_currentclass, obj->nspace->theclass, &depth, &isambigbase);
-
- CClass_CheckStaticAccess(path, obj->nspace->theclass, obj->access);
- }
-}
-
-void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) {
- if (path) {
- if ((path = CClass_PathCleanup(path, NULL))) {
- if (!CClass_CanAccess(path, objec->access))
- CError_Error(CErrorStr187);
- return;
- }
- }
-
- if (
- objec->access != ACCESSPUBLIC &&
- IS_TYPE_ENUM(objec->type) &&
- TYPE_ENUM(objec->type)->nspace &&
- TYPE_ENUM(objec->type)->nspace->theclass
- )
- CClass_CheckStaticAccess(NULL, TYPE_ENUM(objec->type)->nspace->theclass, objec->access);
-}
-
-static Type *CClass_PointerTypeCopy(Type *type) {
- Type *copy;
-
- switch (type->type) {
- case TYPEPOINTER:
- case TYPEARRAY:
- copy = galloc(sizeof(TypePointer));
- *TYPE_POINTER(copy) = *TYPE_POINTER(type);
- TPTR_TARGET(copy) = CClass_PointerTypeCopy(TPTR_TARGET(copy));
- return copy;
- case TYPEMEMBERPOINTER:
- copy = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(copy) = *TYPE_MEMBER_POINTER(type);
- return copy;
- default:
- return type;
- }
-}
-
-Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) {
- Type *inner;
-
- qual2 = qual2 & (Q_CONST | Q_VOLATILE);
- if (qual1 & Q_MUTABLE)
- qual2 &= ~Q_CONST;
- qual1 = qual1 & (Q_CONST | Q_VOLATILE);
-
- inner = type;
- while (IS_TYPE_ARRAY(inner))
- inner = TPTR_TARGET(inner);
-
- switch (inner->type) {
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- if (qual2) {
- type = CClass_PointerTypeCopy(type);
- inner = type;
- while (IS_TYPE_ARRAY(inner))
- inner = TPTR_TARGET(inner);
-
- switch (inner->type) {
- case TYPEPOINTER:
- TPTR_QUAL(inner) |= qual2;
- break;
- case TYPEMEMBERPOINTER:
- TYPE_MEMBER_POINTER(inner)->qual |= qual2;
- break;
- default:
- CError_FATAL(3125);
- }
- }
- break;
- default:
- qual1 |= qual2;
- }
-
- *outflags = qual1;
- return type;
-}
-
-static void CClass_OptimizeBitFieldAccess(Type **ptype, SInt32 *poffset) {
- Type *innertype;
- TypeBitfield *newtype;
- short i;
-
- innertype = TYPE_BITFIELD(*ptype)->bitfieldtype;
- if (TYPE_BITFIELD(*ptype)->bitlength == 8) {
- switch (TYPE_BITFIELD(*ptype)->offset) {
- case 0:
- i = 0;
- break;
- case 8:
- i = 1;
- break;
- case 16:
- i = 2;
- break;
- case 24:
- i = 3;
- break;
- default:
- i = -1;
- break;
- }
-
- if (i >= 0) {
- if (innertype->size != 1) {
- if (is_unsigned(TYPE_BITFIELD(*ptype)->bitfieldtype))
- *ptype = TYPE(&stunsignedchar);
- else
- *ptype = TYPE(&stsignedchar);
- } else {
- *ptype = innertype;
- }
- *poffset += i;
- return;
- }
- }
-
- if (TYPE_BITFIELD(*ptype)->bitlength == 16) {
- switch (TYPE_BITFIELD(*ptype)->offset) {
- case 0:
- i = 0;
- break;
- case 16:
- i = 2;
- break;
- default:
- i = -1;
- break;
- }
-
- if (i >= 0) {
- if (innertype->size != stsignedshort.size) {
- if (is_unsigned(innertype))
- *ptype = TYPE(&stunsignedshort);
- else
- *ptype = TYPE(&stsignedshort);
- } else {
- *ptype = innertype;
- }
- *poffset += i;
- return;
- }
- }
-
- if (TYPE_BITFIELD(*ptype)->bitlength == 32 && TYPE_BITFIELD(*ptype)->offset == 0) {
- if (innertype->size != stsignedlong.size) {
- if (is_unsigned(innertype))
- *ptype = TYPE(&stunsignedlong);
- else
- *ptype = TYPE(&stsignedlong);
- } else {
- *ptype = innertype;
- }
- return;
- }
-
- if ((*ptype)->size != stsignedchar.size) {
- i = TYPE_BITFIELD(*ptype)->offset + TYPE_BITFIELD(*ptype)->bitlength - 1;
-
- if (TYPE_BITFIELD(*ptype)->bitlength < 8 && (TYPE_BITFIELD(*ptype)->offset & 0xFFF8) == (i & 0xFFF8)) {
- newtype = galloc(sizeof(TypeBitfield));
- *newtype = *TYPE_BITFIELD(*ptype);
- *ptype = TYPE(newtype);
-
- i = 0;
- if (newtype->offset >= 8)
- i = 1;
- if (newtype->offset >= 16)
- i = 2;
- if (newtype->offset >= 24)
- i = 3;
- *poffset += i;
- newtype->offset -= 8 * i;
-
- newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedchar) : TYPE(&stsignedchar);
- newtype->size = newtype->bitfieldtype->size;
- return;
- }
-
- if ((*ptype)->size != stsignedshort.size) {
- if (TYPE_BITFIELD(*ptype)->bitlength < 16 && (TYPE_BITFIELD(*ptype)->offset & 0xFFF0) == (i & 0xFFF0)) {
- newtype = galloc(sizeof(TypeBitfield));
- *newtype = *TYPE_BITFIELD(*ptype);
- *ptype = TYPE(newtype);
-
- i = 0;
- if (newtype->offset >= 16)
- i = stsignedshort.size;
- *poffset += i;
- newtype->offset -= 8 * i;
-
- newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedshort) : TYPE(&stsignedshort);
- newtype->size = newtype->bitfieldtype->size;
- return;
- }
- }
- }
-}
-
-ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) {
- Type *innertype;
- UInt32 flags;
-
- innertype = NULL;
-
- if (IS_TYPE_CLASS(classexpr->rtype) && (TYPE_CLASS(classexpr->rtype)->flags & CLASS_HANDLEOBJECT)) {
- classexpr = makemonadicnode(classexpr, EINDIRECT);
- classexpr->data.monadic->rtype = CDecl_NewPointerType(classexpr->rtype);
- }
-
- if (IS_TYPE_BITFIELD(type)) {
- innertype = TYPE_BITFIELD(type)->bitfieldtype;
- CClass_OptimizeBitFieldAccess(&type, &offset);
- }
-
- if (offset && !canadd(classexpr->data.monadic, offset)) {
- classexpr->data.monadic = makediadicnode(
- classexpr->data.monadic,
- intconstnode(TYPE(&stunsignedlong), offset),
- EADD);
- optimizecomm(classexpr->data.monadic);
- }
-
- if (innertype) {
- if (IS_TYPE_BITFIELD(type)) {
- classexpr->data.monadic = makemonadicnode(classexpr->data.monadic, EBITFIELD);
- classexpr->data.monadic->rtype = type;
- classexpr->rtype = TYPE_BITFIELD(type)->bitfieldtype;
- } else {
- classexpr->rtype = type;
- }
- } else {
- classexpr->rtype = type;
- }
-
- classexpr->rtype = CClass_CombineClassAccessQualifiers(classexpr->rtype, qual, ENODE_QUALS(classexpr), &flags);
- classexpr->flags = flags;
- return classexpr;
-}