diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CRTTI.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-main.tar.gz MWCC-main.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/CRTTI.c')
-rw-r--r-- | compiler_and_linker/unsorted/CRTTI.c | 940 |
1 files changed, 0 insertions, 940 deletions
diff --git a/compiler_and_linker/unsorted/CRTTI.c b/compiler_and_linker/unsorted/CRTTI.c deleted file mode 100644 index 3881153..0000000 --- a/compiler_and_linker/unsorted/CRTTI.c +++ /dev/null @@ -1,940 +0,0 @@ -#include "compiler/CRTTI.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CInit.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CScope.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/types.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CPrep.h" - -typedef struct Offset { - struct Offset *next; - SInt32 offset; -} Offset; - -static Offset *crtti_offsets; -static OLinkList *crtti_olinks; - -// forward decls -static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual); - -typedef struct RTTISubClassList { - struct RTTISubClassList *next; - TypeClass *base; - SInt32 voffset; -} RTTISubClassList; - -typedef struct RTTIBaseList { - struct RTTIBaseList *next; - TypeClass *base; - RTTISubClassList *subclasses; - SInt32 voffset; - short numsubclasses; - Boolean x12; - Boolean x13; -} RTTIBaseList; - -static RTTIBaseList *CRTTI_CreateBaseList(TypeClass *tclass, TypeClass *tclassbase, RTTIBaseList *list, SInt32 voffset, Boolean flag) { - RTTIBaseList *scan; - ClassList *base; - Boolean flag27; - SInt32 newvoffset; - - if (tclass != tclassbase) { - flag27 = 0; - - for (scan = list; scan; scan = scan->next) { - if (scan->base == tclassbase) { - if (scan->voffset == voffset) { - if (!flag) - scan->x12 = 0; - flag27 = 0; - } else { - scan->x13 = 1; - flag27 = 1; - } - break; - } - } - - if (!scan || flag27) { - scan = lalloc(sizeof(RTTIBaseList)); - memclrw(scan, sizeof(RTTIBaseList)); - - scan->next = list; - list = scan; - scan->base = tclassbase; - scan->voffset = voffset; - scan->x12 = flag; - scan->x13 = flag27; - } - } - - for (base = tclassbase->bases; base; base = base->next) { - if (base->is_virtual) - newvoffset = CClass_VirtualBaseOffset(tclass, base->base); - else - newvoffset = voffset + base->offset; - - list = CRTTI_CreateBaseList(tclass, base->base, list, newvoffset, flag || base->access == ACCESSPRIVATE); - } - - return list; -} - -static void CRTTI_CreateSubClassList(TypeClass *tclass, RTTIBaseList *baselist, TypeClass *tclassbase, SInt32 voffset, Boolean flag) { - ClassList *base; - RTTISubClassList *scan; - SInt32 newvoffset; - - if (baselist->base != tclassbase) { - for (scan = baselist->subclasses; scan; scan = scan->next) { - if (scan->base == tclassbase && scan->voffset == voffset) - break; - } - - if (!scan) { - scan = lalloc(sizeof(RTTISubClassList)); - scan->next = baselist->subclasses; - baselist->subclasses = scan; - - scan->base = tclassbase; - scan->voffset = voffset; - baselist->numsubclasses++; - } - } - - for (base = tclassbase->bases; base; base = base->next) { - if (base->access == ACCESSPUBLIC) { - if (base->is_virtual) { - if (!flag) - continue; - newvoffset = CClass_VirtualBaseOffset(tclass, base->base); - } else { - newvoffset = voffset + base->offset; - } - - CRTTI_CreateSubClassList(tclass, baselist, base->base, newvoffset, flag); - } - } -} - -static Object *CRTTI_CreateBaseListObject(TypeClass *tclass) { - RTTIBaseList *baselist; - OLinkList *refs; - Object *object; - SInt32 *buf; - SInt32 size; - short count1; - short count2; - short total; - OLinkList *ref; - RTTIBaseList *scan; - RTTISubClassList *subclass; - SInt32 *work; - SInt32 *work2; - - baselist = CRTTI_CreateBaseList(tclass, tclass, NULL, 0, 0); - if (!baselist) - return NULL; - - count1 = 0; - count2 = 0; - total = 0; - - for (scan = baselist; scan; scan = scan->next) { - if (scan->x13 || scan->x12) { - CRTTI_CreateSubClassList(tclass, scan, scan->base, scan->voffset, scan->x13 == 0); - if (scan->numsubclasses) { - total += scan->numsubclasses; - count2++; - } - } else { - count1++; - } - } - - if (!count1 && !count2) - return NULL; - - size = (count1 + total) * 8 + count2 * 12 + 4; - buf = lalloc(size); - memclrw(buf, size); - - object = CParser_NewCompilerDefDataObject(); - object->name = CParser_GetUniqueName(); - object->type = CDecl_NewStructType(size, 4); - object->qual = Q_CONST; - object->sclass = TK_STATIC; - refs = NULL; - - work = buf; - - if (count1) { - for (scan = baselist; scan; scan = scan->next) { - if (!scan->x12 && !scan->x13) { - ref = lalloc(sizeof(OLinkList)); - ref->next = refs; - refs = ref; - - ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0); - ref->offset = ((char *) work) - ((char *) buf); - ref->somevalue = 0; - - work[1] = CTool_EndianConvertWord32(scan->voffset); - work += 2; - } - } - } - - if (count2) { - for (scan = baselist; scan; scan = scan->next) { - if (scan->numsubclasses) { - ref = lalloc(sizeof(OLinkList)); - ref->next = refs; - refs = ref; - - ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0); - ref->offset = ((char *) work) - ((char *) buf); - ref->somevalue = 0; - - work[1] = CTool_EndianConvertWord32(scan->voffset | 0x80000000); - work[2] = CTool_EndianConvertWord32(scan->numsubclasses); - work2 = work + 3; - - for (subclass = scan->subclasses; subclass; subclass = subclass->next) { - ref = lalloc(sizeof(OLinkList)); - ref->next = refs; - refs = ref; - - ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(subclass->base), 0); - ref->offset = ((char *) work2) - ((char *) buf); - ref->somevalue = 0; - - work2[1] = CTool_EndianConvertWord32(subclass->voffset); - work2 += 2; - } - - work = work2; - } - } - } - - CInit_DeclareData(object, buf, refs, object->type->size); - return object; -} - -static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual) { - Object *baselistobj; - Object *nameobj; - HashNameNode *rttiname; - OLinkList *refs; - char *namestr; - int namelen; - Object *object; - NameSpaceObjectList *list; - TypePointer tptr_copy; - TypeMemberPointer tmemptr_copy; - UInt32 data[2]; - - switch (type->type) { - case TYPEPOINTER: - if (TPTR_QUAL(type) & (Q_CONST | Q_VOLATILE)) { - tptr_copy = *TYPE_POINTER(type); - tptr_copy.qual &= ~(Q_CONST | Q_VOLATILE); - type = TYPE(&tptr_copy); - } - break; - case TYPEMEMBERPOINTER: - if (TYPE_MEMBER_POINTER(type)->qual & (Q_CONST | Q_VOLATILE)) { - tmemptr_copy = *TYPE_MEMBER_POINTER(type); - tmemptr_copy.qual &= ~(Q_CONST | Q_VOLATILE); - type = TYPE(&tmemptr_copy); - } - break; - default: - qual = 0; - } - - if (IS_TYPE_CLASS(type) && type->size == 0) { - CDecl_CompleteType(type); - if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED)) - CError_Error(CErrorStr136, type, 0); - } - - rttiname = CMangler_RTTIObjectName(type, qual); - list = CScope_FindName(cscope_root, rttiname); - - if (!list || (object = OBJECT(list->object))->otype != OT_OBJECT || object->datatype != DDATA) { - namestr = CError_GetTypeName(type, qual, 0); - namelen = strlen(namestr) + 1; - nameobj = CInit_DeclareString(namestr, namelen, 0, 0); - - baselistobj = NULL; - if (IS_TYPE_CLASS(type)) - baselistobj = CRTTI_CreateBaseListObject(TYPE_CLASS(type)); - - memclrw(data, sizeof(data)); - - object = CParser_NewCompilerDefDataObject(); - object->name = rttiname; - object->type = CDecl_NewStructType(sizeof(data), 4); - object->qual = Q_CONST; - object->sclass = TK_STATIC; - - refs = lalloc(sizeof(OLinkList)); - refs->next = NULL; - refs->obj = nameobj; - refs->offset = 0; - refs->somevalue = 0; - - if (baselistobj) { - refs->next = lalloc(sizeof(OLinkList)); - refs->next->next = NULL; - refs->next->obj = baselistobj; - refs->next->offset = 4; - refs->next->somevalue = 0; - } - - CScope_AddGlobalObject(object); - CInit_DeclareData(object, data, refs, object->type->size); - } - - return object; -} - -static void CRTTI_ConstructVTableHeader(TypeClass *tclass1, TypeClass *tclass2, Object *typeinfoObj, char *data, SInt32 offset, SInt32 voffset) { - ClassList *base; - Offset *o; - OLinkList *olink; - SInt32 tmp; - SInt32 newoffset; - SInt32 newvoffset; - - if (tclass2->vtable->owner == tclass2) { - for (o = crtti_offsets; o; o = o->next) { - if (o->offset == voffset) - break; - } - - if (!o) { - o = lalloc(sizeof(Offset)); - o->next = crtti_offsets; - o->offset = voffset; - crtti_offsets = o; - - olink = lalloc(sizeof(OLinkList)); - olink->next = crtti_olinks; - olink->obj = typeinfoObj; - olink->offset = voffset; - olink->somevalue = 0; - crtti_olinks = olink; - - *((SInt32 *) (data + voffset + 4)) = CTool_EndianConvertWord32(-offset); - } else { - tmp = *((SInt32 *) (data + voffset + 4)); - CError_ASSERT(404, tmp == CTool_EndianConvertWord32(-offset)); - } - } - - for (base = tclass2->bases; base; base = base->next) { - if (base->base->vtable) { - if (base->is_virtual) { - newoffset = CClass_VirtualBaseOffset(tclass1, base->base); - newvoffset = CClass_VirtualBaseVTableOffset(tclass1, base->base); - } else { - newoffset = offset + base->offset; - newvoffset = voffset + base->voffset; - } - - CRTTI_ConstructVTableHeader(tclass1, base->base, typeinfoObj, data, newoffset, newvoffset); - } - } -} - -OLinkList *CRTTI_ConstructVTableHeaders(TypeClass *tclass, void *data, OLinkList *links) { - crtti_offsets = NULL; - crtti_olinks = links; - - CRTTI_ConstructVTableHeader( - tclass, tclass, - CRTTI_ConstructTypeInfoObject(TYPE(tclass), 0), - data, 0, 0); - - return crtti_olinks; -} - -static Type *CRTTI_FindTypeInfoType(void) { - NameSpace *nspace; - NameSpaceObjectList *list; - Type *type; - - if ((list = CScope_FindName(cscope_root, GetHashNameNodeExport("std"))) && list->object->otype == OT_NAMESPACE) - nspace = OBJ_NAMESPACE(list->object)->nspace; - else - nspace = cscope_root; - - type = CScope_GetLocalTagType(nspace, GetHashNameNodeExport("type_info")); - if (type && IS_TYPE_CLASS(type) && type->size) - return type; - - CError_Error(CErrorStr140, "::std::type_info"); - return TYPE(&stchar); -} - -ENode *CRTTI_ParseTypeID(void) { - ENode *expr; - Type *type; - Type *typeinfoType; - UInt32 qual; - - if (!copts.RTTI) - CError_Warning(CErrorStr257); - - typeinfoType = CRTTI_FindTypeInfoType(); - - if (lex() != '(') { - CError_Error(CErrorStr114); - return nullnode(); - } - - tk = lex(); - if ((type = CParser_ParseTypeID(&qual, NULL))) { - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - - if (IS_TYPE_REFERENCE(type)) - type = TPTR_TARGET(type); - } else { - expr = s_expression(); - - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - - type = expr->rtype; - qual = ENODE_QUALS(expr); - - if (IS_TYPE_REFERENCE(type)) - type = TPTR_TARGET(type); - - if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->vtable) { - expr = funccallexpr( - Rgtid_func, - getnodeaddress(expr, 0), - intconstnode(TYPE(&stsignedlong), TYPE_CLASS(type)->vtable->offset), - NULL, - NULL); - expr->rtype = CDecl_NewPointerType(typeinfoType); - - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = typeinfoType; - expr->flags = ENODE_FLAG_CONST; - return expr; - } - } - - expr = create_objectrefnode(CRTTI_ConstructTypeInfoObject(type, qual)); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = typeinfoType; - expr->flags = ENODE_FLAG_CONST; - return expr; -} - -static void CRTTI_ConstCastQualCheck(UInt32 qual1, UInt32 qual2) { - if ( - ((qual1 & Q_CONST) && !(qual2 & Q_CONST)) || - ((qual1 & Q_VOLATILE) && !(qual2 & Q_VOLATILE)) - ) - CError_Error(CErrorStr258); -} - -static void CRTTI_ConstCastCheck(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2) { - Boolean flag = 1; - if (IS_TYPE_REFERENCE(type2)) { - type2 = TPTR_TARGET(type2); - flag = 0; - } - - while (1) { - if (type1->type != type2->type) - break; - - switch (type1->type) { - case TYPEPOINTER: - if (!flag) - CRTTI_ConstCastQualCheck(TPTR_QUAL(type1), TPTR_QUAL(type2)); - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - flag = 0; - continue; - - case TYPEMEMBERPOINTER: - if (!flag) - CRTTI_ConstCastQualCheck(TYPE_MEMBER_POINTER(type1)->qual, TYPE_MEMBER_POINTER(type2)->qual); - type1 = TYPE_MEMBER_POINTER(type1)->ty1; - type2 = TYPE_MEMBER_POINTER(type2)->ty1; - flag = 0; - continue; - } - - break; - } - - if (!flag && !IS_TYPE_FUNC(type1) && !IS_TYPE_FUNC(type2)) - CRTTI_ConstCastQualCheck(CParser_GetCVTypeQualifiers(type1, qual1), CParser_GetCVTypeQualifiers(type2, qual2)); -} - -static ENode *CRTTI_ParseCast(DeclInfo *di) { - ENode *expr; - - if (lex() != '<') { - CError_Error(CErrorStr230); - return NULL; - } - - tk = lex(); - - memclrw(di, sizeof(DeclInfo)); - CParser_GetDeclSpecs(di, 0); - scandeclarator(di); - - if (di->name) - CError_Error(CErrorStr164); - - if (tk != '>') { - CError_Error(CErrorStr231); - return NULL; - } - - if (lex() != '(') { - CError_Error(CErrorStr114); - return NULL; - } - - tk = lex(); - expr = s_expression(); - if (!IS_TYPE_REFERENCE(di->thetype)) - expr = pointer_generation(expr); - - if (tk != ')') { - CError_Error(CErrorStr115); - return NULL; - } - - tk = lex(); - return expr; -} - -static void CRTTI_IncompleteCheck(Type *type) { - if (IS_TYPE_POINTER_ONLY(type)) - type = TPTR_TARGET(type); - - if (IS_TYPE_CLASS(type) && type->size == 0) { - CDecl_CompleteType(type); - if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED)) - CError_Error(CErrorStr136, type, 0); - } -} - -static Boolean CRTTI_IsSameType(Type *a, Type *b) { - while (1) { - if (a->type != b->type) - return 0; - - switch (a->type) { - case TYPEVOID: - return 1; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPESTRUCT: - return a == b; - case TYPEPOINTER: - a = TPTR_TARGET(a); - b = TPTR_TARGET(b); - continue; - default: - return is_typesame(a, b); - } - } -} - -static ENode *CRTTI_UniversalCast(ENode *expr, Type *type, UInt32 qual, UInt8 mode) { - // type/qual are the target type - Boolean isSimpleCast; - Boolean needsTypcon; - Boolean failed; - - if (ENODE_IS(expr, EOBJLIST)) - return CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1); - - isSimpleCast = needsTypcon = failed = 0; - - switch (type->type) { - case TYPEINT: - case TYPEENUM: - if (mode == 2 && IS_TYPE_POINTER_ONLY(expr->rtype) && type != TYPE(&stbool)) - failed = 1; - break; - - case TYPEPOINTER: - if (TPTR_QUAL(type) & Q_REFERENCE) { - if ( - !CRTTI_IsSameType(TPTR_TARGET(type), expr->rtype) && - mode == 2 && - !( - IS_TYPE_CLASS(TPTR_TARGET(type)) && - IS_TYPE_CLASS(expr->rtype) && - ( - CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(expr->rtype), NULL, 0, 1) || - CClass_IsBaseClass(TYPE_CLASS(expr->rtype), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1) - ) - ) - ) - { - failed = 1; - } - } else if (IS_TYPE_POINTER_ONLY(expr->rtype)) { - if ( - mode == 3 || - CRTTI_IsSameType(type, expr->rtype) || - IS_TYPE_VOID(TPTR_TARGET(type)) || - IS_TYPE_VOID(TPTR_TARGET(expr->rtype)) - ) - { - isSimpleCast = needsTypcon = 1; - } - else if ( - mode == 2 && - !( - IS_TYPE_CLASS(TPTR_TARGET(type)) && - IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && - ( - CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(TPTR_TARGET(expr->rtype)), NULL, 0, 1) || - CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1) - ) - ) - ) - { - failed = 1; - } - } else { - if (IS_TYPE_ENUM(expr->rtype)) - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - - if (IS_TYPE_INT(expr->rtype)) { - if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) { - isSimpleCast = 1; - break; - } - - if (mode != 2) - break; - } - - if (IS_TYPE_CLASS(expr->rtype)) { - if (mode == 2) - break; - } - - failed = 1; - } - break; - } - - if (failed) { - CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual); - return expr; - } - - if (isSimpleCast) { - if (needsTypcon && ENODE_IS(expr, EINDIRECT) && (copts.pointercast_lvalue || !copts.ANSIstrict)) - expr = makemonadicnode(expr, ETYPCON); - - expr->rtype = type; - expr->flags = qual & ENODE_FLAG_QUALS; - return expr; - } - - if (copts.old_argmatch) - return do_typecast(expr, type, qual); - - return CExpr_Convert(expr, type, qual, 1, 1); -} - -ENode *CRTTI_Parse_dynamic_cast(void) { - Boolean isRef; - ENode *expr; - TypeClass *srcclass; - TypeClass *destclass; - ENode *typeinfo; - DeclInfo di; - - expr = CRTTI_ParseCast(&di); - if (!expr) - return nullnode(); - - if (!copts.RTTI) - CError_Warning(CErrorStr257); - - CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual); - if (!IS_TYPE_POINTER_ONLY(di.thetype)) { - CError_Error(CErrorStr164); - return expr; - } - - isRef = (TPTR_QUAL(di.thetype) & Q_REFERENCE) != 0; - - if (IS_TYPE_CLASS(TPTR_TARGET(di.thetype))) { - destclass = TYPE_CLASS(TPTR_TARGET(di.thetype)); - CDecl_CompleteType(TYPE(destclass)); - if (!(destclass->flags & CLASS_COMPLETED)) { - CError_Error(CErrorStr136, destclass, 0); - return expr; - } - } else if (!IS_TYPE_VOID(TPTR_TARGET(di.thetype))) { - CError_Error(CErrorStr164); - return expr; - } else { - destclass = NULL; - } - - if (isRef) { - if (!IS_TYPE_CLASS(expr->rtype)) { - CError_Error(CErrorStr164); - return expr; - } - - srcclass = TYPE_CLASS(expr->rtype); - if (destclass) { - if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1)) - return do_typecast(expr, di.thetype, di.qual); - } - - expr = getnodeaddress(expr, 1); - } else { - if (!IS_TYPE_POINTER_ONLY(expr->rtype) || !IS_TYPE_CLASS(TPTR_TARGET(expr->rtype))) { - CError_Error(CErrorStr164); - return expr; - } - - srcclass = TYPE_CLASS(TPTR_TARGET(expr->rtype)); - if (destclass) { - if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1)) - return do_typecast(expr, di.thetype, di.qual); - } - } - - if (!(srcclass->flags & CLASS_COMPLETED)) { - CError_Error(CErrorStr136, srcclass, 0); - return expr; - } - - if (!srcclass->vtable) { - CError_Error(CErrorStr164); - return expr; - } - - if (srcclass->sominfo) { - CError_Error(CErrorStr164); - return expr; - } - - if (destclass) { - typeinfo = create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(destclass), 0)); - if (destclass->sominfo) { - CError_Error(CErrorStr164); - return expr; - } - } else { - typeinfo = nullnode(); - } - - expr = CExpr_FuncCallSix( - Rdync_func, - expr, - intconstnode(TYPE(&stsignedlong), srcclass->vtable->offset), - typeinfo, - create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(srcclass), 0)), - intconstnode(TYPE(&stsignedshort), isRef), - NULL - ); - - if (isRef) { - expr->rtype = CDecl_NewPointerType(TYPE(destclass)); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TYPE(destclass); - } else { - expr->rtype = di.thetype; - } - expr->flags = di.qual & ENODE_FLAG_QUALS; - return expr; -} - -ENode *CRTTI_Parse_static_cast(void) { - ENode *expr; - DeclInfo di; - - expr = CRTTI_ParseCast(&di); - if (!expr) - return nullnode(); - - CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual); - - if (IS_TYPE_REFERENCE(di.thetype)) { - if (IS_TYPE_CLASS(expr->rtype) && CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual)) { - expr = CExpr_Convert(expr, di.thetype, di.qual, 0, 1); - CError_ASSERT(959, IS_TYPE_POINTER_ONLY(expr->rtype)); - - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TPTR_TARGET(di.thetype); - expr->flags = di.qual & ENODE_FLAG_QUALS; - return expr; - } - } else { - if (CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual)) - return CExpr_Convert(expr, di.thetype, di.qual, 1, 1); - } - - if (!IS_TYPE_VOID(di.thetype) && !(IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_VOID(TPTR_TARGET(expr->rtype)))) { - CRTTI_IncompleteCheck(di.thetype); - CRTTI_IncompleteCheck(expr->rtype); - } - - return CRTTI_UniversalCast(expr, di.thetype, di.qual, 2); -} - -ENode *CRTTI_Parse_reinterpret_cast(void) { - ENode *expr; - Type *origtype; - ENode *lvalue; - DeclInfo di; - - expr = CRTTI_ParseCast(&di); - if (!expr) - return nullnode(); - - CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual); - - if (IS_TYPE_REFERENCE(di.thetype)) { - lvalue = CExpr_LValue(expr, 0, 1); - if (!ENODE_IS(lvalue, EINDIRECT)) - return lvalue; - - lvalue->data.monadic->rtype = CDecl_NewPointerType(lvalue->rtype); - expr = lvalue->data.monadic; - origtype = di.thetype; - di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype)); - } else { - origtype = NULL; - } - - switch (di.thetype->type) { - case TYPEINT: - switch (expr->rtype->type) { - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - expr = do_typecast(expr, di.thetype, di.qual); - break; - default: - CError_Error(CErrorStr164); - } - break; - case TYPEPOINTER: - switch (expr->rtype->type) { - case TYPEINT: - case TYPEENUM: - if (origtype) - di.thetype = origtype; - expr = do_typecast(expr, di.thetype, di.qual); - break; - case TYPEPOINTER: - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = di.thetype; - expr->flags = di.qual & ENODE_FLAG_QUALS; - break; - default: - CError_Error(CErrorStr164); - } - break; - case TYPEMEMBERPOINTER: - if (IS_TYPE_MEMBERPOINTER(expr->rtype)) { - if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(di.thetype)->ty1)) { - if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) { - expr->rtype = di.thetype; - expr->flags = di.qual & ENODE_FLAG_QUALS; - break; - } - } else { - if (!IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) { - expr->rtype = di.thetype; - expr->flags = di.qual & ENODE_FLAG_QUALS; - break; - } - } - } - expr = do_typecast(expr, di.thetype, di.qual); - break; - default: - CError_Error(CErrorStr164); - } - - if (origtype && IS_TYPE_POINTER_ONLY(expr->rtype)) { - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TPTR_TARGET(di.thetype); - } - - return expr; -} - -ENode *CRTTI_Parse_const_cast(void) { - DeclInfo di; - ENode *expr; - - if (!(expr = CRTTI_ParseCast(&di))) - return nullnode(); - - if (IS_TYPE_POINTER_ONLY(di.thetype)) { - if (TPTR_QUAL(di.thetype) & Q_REFERENCE) { - if (!iscpp_typeequal(TPTR_TARGET(di.thetype), expr->rtype)) - CError_Error(CErrorStr164); - - if (ENODE_IS(expr, EINDIRECT)) { - expr->rtype = TPTR_TARGET(di.thetype); - expr->flags = di.qual & ENODE_FLAG_QUALS; - } else { - CError_Error(CErrorStr142); - } - } else { - if (!iscpp_typeequal(di.thetype, expr->rtype)) - CError_Error(CErrorStr164); - - expr = do_typecast(expr, di.thetype, di.qual); - } - } else if (IS_TYPE_MEMBERPOINTER(di.thetype)) { - if (!iscpp_typeequal(di.thetype, expr->rtype)) - CError_Error(CErrorStr164); - - expr = do_typecast(expr, di.thetype, di.qual); - } else { - if (!is_typesame(di.thetype, expr->rtype)) - CError_Error(CErrorStr164); - else - expr = do_typecast(expr, di.thetype, di.qual); - } - - return expr; -} |