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/CExprConvMatch.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/CExprConvMatch.c')
-rw-r--r-- | compiler_and_linker/unsorted/CExprConvMatch.c | 2518 |
1 files changed, 0 insertions, 2518 deletions
diff --git a/compiler_and_linker/unsorted/CExprConvMatch.c b/compiler_and_linker/unsorted/CExprConvMatch.c deleted file mode 100644 index 5cc145f..0000000 --- a/compiler_and_linker/unsorted/CExprConvMatch.c +++ /dev/null @@ -1,2518 +0,0 @@ -#include "compiler/CExpr.h" -#include "compiler/CABI.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CInt64.h" -#include "compiler/CFunc.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CObjC.h" -#include "compiler/CParser.h" -#include "compiler/CScope.h" -#include "compiler/CTemplateFunc.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct StandardConv { - Type *type1; - Type *type2; - UInt32 qual1; - UInt32 qual2; - Boolean x10; // unknown - Boolean x11; - Boolean x12; - Boolean x13; - Boolean x14; - Boolean x15; -} StandardConv; - -typedef enum EImplicitConvType { - ICT_0, - ICT_1, - ICT_2, - ICT_3 -} EImplicitConvType; - -typedef struct ImplicitConv { - EImplicitConvType type; - union { - struct { - Object *x2; - StandardConv standardConv; - } ic2; - struct { - StandardConv standardConv; - } ic3; - } u; -} ImplicitConv; - -typedef struct ConversionTypeList { - struct ConversionTypeList *next; - Object *func; - Type *type; - UInt32 qual; -} ConversionTypeList; - -typedef struct Match { - struct Match *next; - Object *object; - Object *specialfunc; - Type *type; - UInt32 qual; - Type *type2; - UInt32 qual2; - ImplicitConv conv[3]; -} Match; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -// forward decls -static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean flag2, Boolean flag3); - -static Type *CExpr_GetImplictObjectParamType(Object *object, UInt32 *qual) { - Type *type; - - CError_ASSERT(98, IS_TYPE_FUNC(object->type)); - CError_ASSERT(99, TYPE_FUNC(object->type)->flags & FUNC_METHOD); - CError_ASSERT(100, !TYPE_METHOD(object->type)->is_static); - CError_ASSERT(101, TYPE_METHOD(object->type)->args); - - type = CDecl_NewRefPointerType(TYPE(TYPE_METHOD(object->type)->theclass)); - *qual = TYPE_METHOD(object->type)->args->qual & Q_CV; - return type; -} - -static Type *CExpr_GetParamType(Object *object, int index, UInt32 *qual) { - FuncArg *arg; - - CError_ASSERT(120, IS_TYPE_FUNC(object->type)); - CError_ASSERT(121, arg = TYPE_FUNC(object->type)->args); - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) - CError_ASSERT(125, arg = arg->next); - - while (index > 0) { - CError_ASSERT(129, arg = arg->next); - index--; - } - - *qual = arg->qual & Q_CV; - return arg->type; -} - -static Boolean CExpr_HasNParams(Object *object, int count) { - FuncArg *arg; - int i; - - CError_ASSERT(146, IS_TYPE_FUNC(object->type)); - CError_ASSERT(147, arg = TYPE_FUNC(object->type)->args); - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) - arg = arg->next; - - i = 0; - while (arg) { - arg = arg->next; - i++; - } - - return i == count; -} - -typedef enum TypeCompareMode { - TCM_0, - TCM_1, - TCM_2 -} TypeCompareMode; - -static Boolean CExpr_TypeCompare(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB, TypeCompareMode mode) { - if (typeA->type != typeB->type) - return 0; - - switch (mode) { - case TCM_0: - while (1) { - switch (typeA->type) { - case TYPEPOINTER: - typeA = TPTR_TARGET(typeA); - typeB = TPTR_TARGET(typeB); - if (typeA->type != typeB->type) - return 0; - continue; - - case TYPEMEMBERPOINTER: - if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2)) - return 0; - typeA = TYPE_MEMBER_POINTER(typeA)->ty1; - typeB = TYPE_MEMBER_POINTER(typeB)->ty1; - if (typeA->type != typeB->type) - return 0; - continue; - } - break; - } - break; - - case TCM_1: - switch (typeA->type) { - case TYPEPOINTER: - if ((qualA & Q_CV) != (qualB & Q_CV)) - return 0; - - typeA = TPTR_TARGET(typeA); - typeB = TPTR_TARGET(typeB); - break; - - case TYPEMEMBERPOINTER: - if ((qualA & Q_CV) != (qualB & Q_CV)) - return 0; - - if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2)) - return 0; - typeA = TYPE_MEMBER_POINTER(typeA)->ty1; - typeB = TYPE_MEMBER_POINTER(typeB)->ty1; - break; - } - break; - - case TCM_2: - if ((qualA & Q_CV) != (qualB & Q_CV)) - return 0; - break; - } - - return is_typesame(typeA, typeB); -} - -static int CExpr_IsReferenceCompatible(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB) { - if (CParser_IsSameOrMoreCVQualified(CParser_GetCVTypeQualifiers(typeA, qualA), CParser_GetCVTypeQualifiers(typeB, qualB))) { - if (CExpr_TypeCompare(typeA, qualA, typeB, qualB, TCM_1)) - return 1; - - if (IS_TYPE_CLASS(typeB) && IS_TYPE_CLASS(typeA)) { - short depth; - Boolean isambigbase; - if (CClass_GetBasePath(TYPE_CLASS(typeB), TYPE_CLASS(typeA), &depth, &isambigbase)) - return 2; - } - } - - return 0; -} - -static Boolean CExpr_IsBaseOf(TypeClass *baseclass, TypeClass *superclass) { - ClassList *base; - - for (base = superclass->bases; base; base = base->next) { - if (base->base == baseclass || CExpr_IsBaseOf(baseclass, base->base)) - return 1; - } - - return 0; -} - -static Boolean CExpr_IsBetterClassConversion(TypeClass *a, TypeClass *b, TypeClass *c, TypeClass *d) { - if (a == c) - return CExpr_IsBaseOf(d, b); - if (b == d) - return CExpr_IsBaseOf(a, c); - return 0; -} - -CW_INLINE Boolean Inline_501D40(Type *a, Type *b) { - return (a == TYPE(&stbool)) && (IS_TYPE_POINTER_ONLY(b) || IS_TYPE_MEMBERPOINTER(b)); -} - -static Boolean CExpr_IsBetterStandardConv(StandardConv *a, StandardConv *b) { - Boolean flag10; - Boolean flag3; - - flag10 = 1; - flag3 = 0; - - if (b->x11) { - if (!a->x11) - flag3 = 1; - } else { - if (a->x11) - flag10 = 0; - } - - if (b->x12) { - if (!a->x12) - flag3 = 1; - } else { - if (a->x12) - flag10 = 0; - } - - if (b->x13) { - if (a->x13) { - if (Inline_501D40(b->type2, b->type1)) { - if (!Inline_501D40(a->type2, a->type1)) - return 1; - } else { - if (Inline_501D40(a->type2, a->type1)) - return 0; - } - } else { - flag3 = 1; - } - } else { - if (a->x13) - flag10 = 0; - } - - if (flag10 && flag3) - return 1; - - if (!a->x13) { - if (b->x13) - return 1; - - if (a->x12) { - if (!b->x12) - return 0; - } else { - if (b->x12) - return 1; - } - } else { - if (!b->x13) - return 0; - } - - if ( - IS_TYPE_POINTER_ONLY(a->type1) && - IS_TYPE_CLASS(TPTR_TARGET(a->type1)) && - IS_TYPE_POINTER_ONLY(a->type2) && - IS_TYPE_POINTER_ONLY(b->type1) && - IS_TYPE_CLASS(TPTR_TARGET(b->type1)) && - IS_TYPE_POINTER_ONLY(b->type2) - ) - { - if (TPTR_TARGET(b->type2) == &stvoid) { - if (TPTR_TARGET(a->type2) == &stvoid) { - if (CExpr_IsBaseOf(TYPE_CLASS(TPTR_TARGET(a->type1)), TYPE_CLASS(TPTR_TARGET(b->type1)))) - return 1; - } else { - if (TPTR_TARGET(a->type1) == TPTR_TARGET(b->type1) && IS_TYPE_CLASS(TPTR_TARGET(a->type2))) - return 1; - } - } else if (IS_TYPE_CLASS(TPTR_TARGET(a->type2)) && IS_TYPE_CLASS(TPTR_TARGET(b->type2))) { - if (CExpr_IsBetterClassConversion( - TYPE_CLASS(TPTR_TARGET(a->type1)), - TYPE_CLASS(TPTR_TARGET(a->type2)), - TYPE_CLASS(TPTR_TARGET(b->type1)), - TYPE_CLASS(TPTR_TARGET(b->type2)) - )) - return 1; - } - } - - if ( - IS_TYPE_CLASS(a->type1) && - IS_TYPE_CLASS(a->type2) && - IS_TYPE_CLASS(b->type1) && - IS_TYPE_CLASS(b->type2) && - CExpr_IsBetterClassConversion( - TYPE_CLASS(a->type1), - TYPE_CLASS(a->type2), - TYPE_CLASS(b->type1), - TYPE_CLASS(b->type2) - ) - ) - return 1; - - if ( - IS_TYPE_MEMBERPOINTER(a->type1) && - IS_TYPE_MEMBERPOINTER(a->type2) && - IS_TYPE_MEMBERPOINTER(b->type1) && - IS_TYPE_MEMBERPOINTER(b->type2) && - IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2) && - IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2) && - IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2) && - IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2) && - CExpr_IsBetterClassConversion( - TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2), - TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2), - TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2), - TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2) - ) - ) - return 1; - - if ( - a->x14 && - b->x14 && - CExpr_TypeCompare(a->type2, a->qual2, b->type2, b->qual2, TCM_1) && - CParser_IsMoreCVQualified( - CParser_GetTypeQualifiers(b->type2, b->qual2), - CParser_GetTypeQualifiers(a->type2, a->qual2) - ) - ) - return 1; - - return 0; -} - -static Boolean CExpr_IsBetterImplicitConv(ImplicitConv *a, ImplicitConv *b) { - if (a->type > b->type) - return 1; - if (a->type != b->type) - return 0; - - if (a->type == ICT_3) - return CExpr_IsBetterStandardConv(&a->u.ic3.standardConv, &b->u.ic3.standardConv); - - if (a->type == ICT_2 && a->u.ic2.x2 == b->u.ic2.x2 && CExpr_IsBetterStandardConv(&a->u.ic2.standardConv, &b->u.ic2.standardConv)) - return 1; - - return 0; -} - -typedef enum SSCRMode { - SSCR_0, - SSCR_1, - SSCR_2 -} SSCRMode; - -static Boolean CExpr_SetupStandardConversionResult(ENode *expr, Type *type2, UInt32 qual2, SSCRMode mode, Boolean x14, Boolean refFlag, StandardConv *result) { - UInt32 cv1; - UInt32 cv2; - - if (x14) { - if (!CParser_IsConst(type2, qual2)) { - if (!refFlag && !CExpr_IsLValue(expr)) - return 0; - if (mode != SSCR_0 && !IS_TYPE_CLASS(type2)) - return 0; - } - - cv2 = CParser_GetTypeQualifiers(type2, qual2) & Q_CV; - cv1 = CParser_GetTypeQualifiers(expr->rtype, ENODE_QUALS(expr)) & Q_CV; - if (cv2 != cv1 && !CParser_IsMoreCVQualified(cv2, cv1)) - return 0; - } - - memclrw(result, sizeof(StandardConv)); - result->type2 = type2; - result->qual2 = qual2; - result->type1 = expr->rtype; - result->qual1 = ENODE_QUALS(expr); - result->x14 = x14; - - switch (mode) { - case SSCR_0: - break; - case SSCR_1: - result->x12 = 1; - break; - case SSCR_2: - result->x13 = 1; - break; - default: - CError_FATAL(581); - } - - return 1; -} - -typedef enum MysteryEnum { - ME_0, - ME_1, - ME_255 = 255 -} MysteryEnum; - -CW_INLINE MysteryEnum Inline_501FF0(UInt32 qual1, UInt32 qual2) { - if ((qual1 & Q_CV) == (qual2 & Q_CV)) - return ME_0; - - if (((qual2 & Q_CONST) && !(qual1 & Q_CONST)) || ((qual2 & Q_VOLATILE) && !(qual1 & Q_VOLATILE))) - return ME_255; - - return ME_1; -} - -static Boolean CExpr_SetQualConversionResult(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, StandardConv *result) { - Boolean flag = 1; - UInt32 cv1; - UInt32 cv2; - - while (1) { - cv1 = CParser_GetCVTypeQualifiers(type1, qual1); - cv2 = CParser_GetCVTypeQualifiers(type2, qual2); - - switch (Inline_501FF0(cv1, cv2)) { - case ME_0: - break; - - case ME_1: - result->x11 = 1; - if (!flag) - return 0; - break; - - default: - return 0; - } - - if (!(cv1 & Q_CONST)) - flag = 0; - - if (IS_TYPE_POINTER_ONLY(type1)) { - CError_ASSERT(635, IS_TYPE_POINTER_ONLY(type2)); - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - } else { - if (!IS_TYPE_MEMBERPOINTER(type1)) - return 1; - - CError_ASSERT(642, IS_TYPE_MEMBERPOINTER(type2)); - type1 = TYPE_MEMBER_POINTER(type1)->ty1; - type2 = TYPE_MEMBER_POINTER(type2)->ty1; - } - } -} - -static Boolean CExpr_OverloadFuncMatch(NameSpaceObjectList *list, TemplArg *templargs, Type *type, ENode **outExpr) { - Object *object; - TemplFuncInstance *inst; - ENode *expr; - FuncArg *arg; - int i; - ObjectList *objlist; - Object *object26; - ObjectList *objlist25; - ObjectList *objlist24; - Boolean flag23; - - if (!IS_TYPE_POINTER_ONLY(type) || !IS_TYPE_FUNC(type = TPTR_TARGET(type))) - return 0; - - object26 = NULL; - objlist25 = NULL; - objlist24 = NULL; - flag23 = 0; - - while (list) { - object = OBJECT(list->object); - if (object->otype == OT_OBJECT) { - if (IS_TEMPL_FUNC(object->type)) { - if (!flag23 && CTempl_CanDeduceFunc(object, TYPE_FUNC(type), templargs)) { - CError_ASSERT(685, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0)); - if (is_typesame(inst->object->type, type)) { - objlist = lalloc(sizeof(ObjectList)); - objlist->next = objlist24; - objlist->object = object; - objlist24 = objlist; - - if (object26 && object26 != inst->object) { - objlist = lalloc(sizeof(ObjectList)); - objlist->next = objlist25; - objlist->object = inst->object; - objlist25 = objlist; - } else { - object26 = inst->object; - } - } - } - } else if (is_typesame(object->type, type)) { - if (object26 && flag23) { - Object *checkA, *checkB; - checkA = object; - if (checkA->datatype == DALIAS) - checkA = checkA->u.alias.object; - checkB = object26; - if (checkB->datatype == DALIAS) - checkB = checkB->u.alias.object; - if (checkA != checkB) { - objlist = lalloc(sizeof(ObjectList)); - objlist->next = objlist25; - objlist->object = object; - objlist25 = objlist; - } - } else { - objlist25 = NULL; - object26 = object; - } - flag23 = 1; - } - } - list = list->next; - } - - if (object26) { - if (outExpr) { - if (objlist25) { - i = 0; - for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) - i++; - - if (!flag23 && (object = CTempl_PartialOrdering(objlist24->object, objlist24->next, i))) { - CError_ASSERT(741, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0)); - object26 = inst->object; - } else { - CError_OverloadedFunctionError(object26, objlist25); - } - } - - expr = CExpr_MakeObjRefNode(object26, 1); - *outExpr = expr; - expr->rtype = CDecl_NewPointerType(object26->type); - expr->flags = object->qual & ENODE_FLAG_QUALS; - object26->flags |= OBJECT_USED; - if (object26->datatype == DINLINEFUNC) - CError_Error(CErrorStr175); - } - - return 1; - } - - return 0; -} - -static Boolean CExpr_StandardConversionMatch(ENode *expr, Type *type2, UInt32 qual2, Boolean x14, StandardConv *result) { - Type *type1; - UInt32 qual1; - Boolean refFlag; - Type *inner2; - Type *inner1; - SSCRMode mode; - NameSpaceObjectList list; - - if (IS_TYPE_REFERENCE(type2)) { - type2 = TPTR_TARGET(type2); - if (IS_TYPE_POINTER_ONLY(type2)) - expr = pointer_generation(expr); - refFlag = 1; - } else { - if ( - (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type2)) || - (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type2)) - ) - expr = pointer_generation(expr); - refFlag = 0; - } - - type1 = expr->rtype; - qual1 = ENODE_QUALS(expr); - - if (IS_TYPE_POINTER_ONLY(type2)) { - if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) { - if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1))) - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); - } - - if ( - IS_TYPE_INT(expr->rtype) && - ENODE_IS_INDIRECT_TO(expr, EOBJREF) && - (expr->data.monadic->data.objref->qual & Q_INLINE_DATA) && - CInt64_IsZero(&expr->data.monadic->data.objref->u.data.u.intconst) - ) - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); - - if (ENODE_IS(expr, EOBJLIST)) - return CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type2, NULL) && - CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); - - if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) { - list.next = NULL; - list.object = OBJ_BASE(expr->data.objref); - return CExpr_OverloadFuncMatch(&list, NULL, type2, NULL) && - CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); - } - - if (IS_TYPE_POINTER_ONLY(type1)) { - if ( - ENODE_IS(expr, ESTRINGCONST) && - TPTR_TARGET(type2) == TPTR_TARGET(type1) && - !(qual2 & Q_CONST) && - ( - TPTR_TARGET(type2) == TYPE(&stchar) || - TPTR_TARGET(type2) == TYPE(&stunsignedchar) || - TPTR_TARGET(type2) == CParser_GetWCharType() - ) - ) - { - if ( - CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result) && - CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1 & ~Q_CONST, result) - ) - { - result->x11 = 1; - return 1; - } else { - return 0; - } - } - - if (copts.objective_c && CObjC_IsCompatibleType(expr->rtype, type2)) - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); - - if (IS_TYPE_VOID(TPTR_TARGET(type2)) || (!copts.cplusplus && IS_TYPE_VOID(TPTR_TARGET(type1)))) { - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, IS_TYPE_VOID(TPTR_TARGET(type1)) ? SSCR_0 : SSCR_2, refFlag, x14, result)) { - switch (Inline_501FF0(qual2, CParser_GetCVTypeQualifiers(TPTR_TARGET(type1), qual1))) { - case ME_1: - result->x11 = 1; - case ME_0: - return 1; - default: - return 0; - } - } else { - return 0; - } - } - - inner2 = TPTR_TARGET(type2); - inner1 = TPTR_TARGET(type1); - while (1) { - if (inner2->type != inner1->type) - break; - - switch (inner2->type) { - case TYPEPOINTER: - inner2 = TPTR_TARGET(inner2); - inner1 = TPTR_TARGET(inner1); - continue; - case TYPEMEMBERPOINTER: - if (!is_typesame(TYPE_MEMBER_POINTER(inner2)->ty2, TYPE_MEMBER_POINTER(inner1)->ty2)) - break; - - inner2 = TYPE_MEMBER_POINTER(inner2)->ty1; - inner1 = TYPE_MEMBER_POINTER(inner1)->ty1; - if (!IS_TYPE_POINTER_ONLY(inner2) && !IS_TYPE_MEMBERPOINTER(inner2)) { - if (!is_memberpointerequal(inner2, inner1)) - break; - - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result)) - return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); - else - return 0; - } - continue; - default: - if (!is_typesame(inner2, inner1)) - break; - - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result)) - return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); - else - return 0; - } - - break; - } - - if (IS_TYPE_CLASS(TPTR_TARGET(type2)) && IS_TYPE_CLASS(TPTR_TARGET(type1))) { - short depth; - Boolean isambigbase; - if (CClass_GetBasePath(TYPE_CLASS(TPTR_TARGET(type1)), TYPE_CLASS(TPTR_TARGET(type2)), &depth, &isambigbase)) { - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) - return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); - else - return 0; - } - } - } - - if (copts.mpwc_relax && !copts.cplusplus && IS_TYPE_POINTER_ONLY(type1)) { - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) - return 1; - } - - return 0; - } - - if (is_typesame(type2, type1)) - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); - - if (type2 == TYPE(&stbool)) { - switch (type1->type) { - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result); - default: - return 0; - } - } - - if (IS_TYPE_MEMBERPOINTER(type2)) { - if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) { - if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1))) - return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result); - } - - if (ENODE_IS(expr, EMEMBER)) { - expr = getpointertomemberfunc(expr, type2, 0); - type1 = expr->rtype; - } - - if (IS_TYPE_MEMBERPOINTER(type1)) { - short depth; - Boolean isambigbase; - - CError_ASSERT(996, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2) && IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2)); - if (!is_memberpointerequal(TYPE_MEMBER_POINTER(type2)->ty1, TYPE_MEMBER_POINTER(type1)->ty1)) - return 0; - - if ( - TYPE_MEMBER_POINTER(type2)->ty2 == TYPE_MEMBER_POINTER(type1)->ty2 || - CClass_GetBasePath(TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2), &depth, &isambigbase) - ) - { - if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) - return CExpr_SetQualConversionResult(TYPE_MEMBER_POINTER(type2)->ty1, qual2, TYPE_MEMBER_POINTER(type1)->ty1, qual1, result); - else - return 0; - } - } - - return 0; - } - - mode = SSCR_2; - switch (type1->type) { - case TYPEINT: - switch (type2->type) { - case TYPEINT: - if (TYPE_INTEGRAL(type1)->integral < IT_INT) { - if (type2 == TYPE(&stsignedint)) { - if (type1->size < type2->size || !is_unsigned(type1)) - mode = SSCR_1; - } else if (type2 == TYPE(&stunsignedint)) { - if (type2->size == type1->size && is_unsigned(type1)) - mode = SSCR_1; - } - } - break; - case TYPEFLOAT: - break; - case TYPEENUM: - if (copts.cplusplus) - return 0; - break; - default: - return 0; - } - break; - - case TYPEFLOAT: - switch (type2->type) { - case TYPEINT: - break; - case TYPEFLOAT: - if (type2 == TYPE(&stdouble)) { - if (type1 == TYPE(&stfloat) || type1 == TYPE(&stshortdouble)) - mode = SSCR_1; - } - break; - case TYPEENUM: - if (copts.cplusplus) - return 0; - break; - default: - return 0; - } - break; - - case TYPEENUM: - switch (type2->type) { - case TYPEINT: - if (TYPE_INTEGRAL(TYPE_ENUM(expr->rtype)->enumtype)->integral < IT_INT) { - if (type1->size == type2->size && is_unsigned(TYPE_ENUM(type1)->enumtype)) { - if (type2 == TYPE(&stunsignedint)) - mode = SSCR_1; - } else { - if (type2 == TYPE(&stsignedint)) - mode = SSCR_1; - } - } else { - if (TYPE_ENUM(type1)->enumtype == type2) - mode = SSCR_1; - } - break; - case TYPEFLOAT: - break; - case TYPEENUM: - if (copts.cplusplus) - return 0; - break; - default: - return 0; - } - break; - - case TYPECLASS: { - short depth; - Boolean isambigbase; - - if (!IS_TYPE_CLASS(type1) || !CClass_GetBasePath(TYPE_CLASS(type1), TYPE_CLASS(type2), &depth, &isambigbase)) - return 0; - break; - } - - default: - return 0; - } - - return CExpr_SetupStandardConversionResult(expr, type2, qual2, mode, refFlag, x14, result); -} - -static ENode *CExpr_UserConversion(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result, Boolean flag1, Boolean isExplicit, Boolean flag3) { - Object *object28; - Object *object27; - Object *object26; - ObjectList *objlist25; - ObjectList *objlist24; - ObjectList *objlist; - TypeFunc *tfunc23; - Type *tmptype23; - NameSpaceObjectList *list22; - Boolean flag22; - Boolean flag21; - FuncArg *arg21; - Boolean flag20; - ENode *newExpr; - ENode *funcref; - ENode *tmpExpr; - ENodeList *arglist; - UInt32 q1; - UInt32 q2; - StandardConv sc3; - StandardConv sc2; - StandardConv sc1; - ConversionIterator convIter; - ENodeList myarglist; - ObjectList myobjlist; - BClassList path; - - object28 = NULL; - object27 = NULL; - objlist25 = NULL; - objlist24 = NULL; - - if (type2->size == 0) - CDecl_CompleteType(type2); - if (expr->rtype->size == 0) - CDecl_CompleteType(expr->rtype); - - if (IS_TYPE_CLASS(expr->rtype)) { - CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype)); - flag22 = 1; - while ((object26 = CExpr_ConversionIteratorNext(&convIter))) { - tfunc23 = TYPE_FUNC(object26->type); - if (tfunc23->flags & FUNC_IS_TEMPL) { - object26 = CTempl_DeduceFromConversion(object26, type2, qual2); - if (!object26) - continue; - tfunc23 = TYPE_FUNC(object26->type); - } - - if (flag3) { - if ( - !IS_TYPE_REFERENCE(tfunc23->functype) || - !CExpr_IsReferenceCompatible(type2, qual2, TPTR_TARGET(tfunc23->functype), tfunc23->qual) - ) - continue; - } - - CError_ASSERT(1230, tfunc23->args && IS_TYPE_POINTER_ONLY(tfunc23->args->type)); - - q1 = ENODE_QUALS(expr); - q2 = tfunc23->args->qual; - if ((q1 & Q_CV) != (q2 & Q_CV)) { - if (!flag22) - continue; - if ((q1 & Q_CONST) && !(q2 & Q_CONST)) - continue; - if ((q1 & Q_VOLATILE) && !(q2 & Q_VOLATILE)) - continue; - flag21 = 1; - } else { - flag21 = 0; - } - - newExpr = CExpr_NewENode(ETEMP); - newExpr->rtype = tfunc23->functype; - newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS; - flag20 = 0; - - if (IS_TYPE_REFERENCE(newExpr->rtype)) { - newExpr->rtype = TPTR_TARGET(newExpr->rtype); - if (!CParser_IsConst(newExpr->rtype, tfunc23->qual)) { - newExpr = makemonadicnode(newExpr, EINDIRECT); - newExpr->data.monadic->rtype = TYPE(&void_ptr); - newExpr = makemonadicnode(newExpr, EINDIRECT); - newExpr->data.monadic->rtype = TYPE(&void_ptr); - flag20 = 1; - } - } - - if (CExpr_StandardConversionMatch(newExpr, type2, qual2, 0, &sc1)) { - if (flag22 && !flag21) { - object28 = NULL; - objlist25 = NULL; - flag22 = 0; - } - - if (object28 && object28 != object26) { - if (CExpr_IsBetterStandardConv(&sc3, &sc1)) - continue; - - if (!CExpr_IsBetterStandardConv(&sc1, &sc3)) { - objlist = lalloc(sizeof(ObjectList)); - objlist->next = objlist25; - objlist->object = object28; - objlist25 = objlist; - } else { - objlist25 = NULL; - } - } - - object28 = object26; - sc3 = sc1; - sc3.x15 = flag20; - } - } - } - - if (!flag3 && IS_TYPE_CLASS(type2) && (list22 = CClass_Constructor(TYPE_CLASS(type2)))) { - for (; list22; list22 = list22->next) { - object26 = OBJECT(list22->object); - if ( - object26->otype == OT_OBJECT && - IS_TYPE_FUNC(tfunc23 = TYPE_FUNC(object26->type)) && - (isExplicit || !(object26->qual & Q_EXPLICIT)) - ) - { - if (tfunc23->flags & FUNC_IS_TEMPL) { - myarglist.next = NULL; - myarglist.node = expr; - object26 = CTempl_DeduceFromFunctionCall(object26, NULL, &myarglist); - if (!object26) - continue; - tfunc23 = TYPE_FUNC(object26->type); - } - - if (!(arg21 = tfunc23->args)) - continue; - if (!(arg21 = arg21->next)) - continue; - if ((TYPE_CLASS(type2)->flags & CLASS_HAS_VBASES) && !(arg21 = arg21->next)) - continue; - if (arg21 == &elipsis) - continue; - if (arg21->next && !arg21->next->dexpr && arg21->next != &elipsis) - continue; - - tmptype23 = arg21->type; - if (IS_TYPE_REFERENCE(tmptype23)) { - tmptype23 = TPTR_TARGET(tmptype23); - if (!CParser_IsConst(tmptype23, arg21->qual) && !CExpr_IsLValue(expr)) - continue; - } - - if (CExpr_StandardConversionMatch(expr, tmptype23, arg21->qual, 0, &sc1)) { - if (object27) { - if (object26->u.func.inst && !object27->u.func.inst) - continue; - if (CExpr_IsBetterStandardConv(&sc2, &sc1)) - continue; - - if (!CExpr_IsBetterStandardConv(&sc1, &sc2)) { - if (!object26->u.func.inst && object27->u.func.inst) { - objlist24 = NULL; - } else { - objlist = lalloc(sizeof(ObjectList)); - objlist->next = objlist25; - objlist->object = object28; - objlist25 = objlist; - } - } else { - objlist25 = NULL; - } - } - - object27 = object26; - sc2 = sc1; - } - } - } - } - - if (object28 && object27) { - if (!CExpr_IsBetterStandardConv(&sc2, &sc3)) { - if (!CExpr_IsBetterStandardConv(&sc3, &sc2)) { - if (result) { - result->type = ICT_2; - result->u.ic2.x2 = object28; - result->u.ic2.standardConv = sc3; - } - if (flag1) { - myobjlist.next = NULL; - myobjlist.object = object27; - CError_OverloadedFunctionError(object28, &myobjlist); - } - } else { - object27 = NULL; - } - } else { - object28 = NULL; - } - } - - if (object28) { - if (result) { - result->type = ICT_2; - result->u.ic2.x2 = object28; - result->u.ic2.standardConv = sc3; - } - if (!flag1) - return expr; - if (objlist25) - CError_OverloadedFunctionError(object28, objlist25); - tfunc23 = TYPE_FUNC(object28->type); - CError_ASSERT(1416, IS_TYPEFUNC_METHOD(tfunc23)); - - funcref = create_objectrefnode(object28); - object28->flags |= OBJECT_USED; - - arglist = lalloc(sizeof(ENodeList)); - arglist->next = NULL; - - expr = getnodeaddress(expr, 0); - arglist->node = CExpr_AssignmentPromotion( - expr, - CDecl_NewPointerType(TYPE(TYPE_METHOD(tfunc23)->theclass)), - expr->flags, - 0); - - newExpr = lalloc(sizeof(ENode)); - newExpr->type = EFUNCCALL; - newExpr->cost = 4; - newExpr->rtype = tfunc23->functype; - newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS; - newExpr->data.funccall.funcref = funcref; - newExpr->data.funccall.args = arglist; - newExpr->data.funccall.functype = TYPE_FUNC(object28->type); - newExpr = CExpr_AdjustFunctionCall(newExpr); - newExpr = checkreference(newExpr); - - if (newExpr->rtype != type2) { - if (flag3) { - tmpExpr = CExpr_DerivedToBase(newExpr, type2, qual2, 1, 0, 1); - if (tmpExpr) - return tmpExpr; - } - newExpr = CExpr_Convert(newExpr, type2, qual2, 0, 1); - } - return newExpr; - } - - if (object27) { - if (result) { - result->type = ICT_2; - result->u.ic2.x2 = object27; - result->u.ic2.standardConv = sc2; - } - if (!flag1) - return expr; - if (objlist24) - CError_OverloadedFunctionError(object27, objlist24); - - arglist = lalloc(sizeof(ENodeList)); - arglist->next = NULL; - arglist->node = expr; - - if (TYPE_CLASS(type2)->flags & CLASS_HAS_VBASES) { - arglist->next = lalloc(sizeof(ENodeList)); - arglist->next->node = expr; - arglist->next->next = NULL; - arglist->node = intconstnode(TYPE(&stsignedshort), 1); - } - - path.next = NULL; - path.type = type2; - - tmpExpr = makemonadicnode(create_temp_node(type2), EINDIRECT); - tmpExpr->rtype = type2; - - newExpr = CExpr_GenericFuncCall( - &path, tmpExpr, 0, object27, NULL, NULL, arglist, 0, 0, 1 - ); - - if (ENODE_IS2(newExpr, EFUNCCALL, EFUNCCALLP)) { - newExpr->rtype = CDecl_NewPointerType(type2); - newExpr = makemonadicnode(newExpr, EINDIRECT); - newExpr->rtype = type2; - } - - return newExpr; - } - - return NULL; -} - -static Boolean CExpr_UserConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) { - Boolean flag; - - if (IS_TYPE_REFERENCE(type2)) { - type2 = TPTR_TARGET(type2); - flag = !CParser_IsConst(type2, qual2); - } else { - expr = pointer_generation(expr); - flag = 0; - } - - if (CExpr_UserConversion(expr, type2, qual2, result, 0, 0, flag)) - return 1; - - return 0; -} - -static Boolean CExpr_ImplicitConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) { - if (CExpr_StandardConversionMatch(expr, type2, qual2, 0, &result->u.ic3.standardConv)) { - result->type = ICT_3; - return 1; - } - - if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type2) || (IS_TYPE_REFERENCE(type2) && IS_TYPE_CLASS(TPTR_TARGET(type2)))) { - if (CExpr_UserConversionMatch(expr, type2, qual2, result)) { - result->type = ICT_2; - return 1; - } - } - - return 0; -} - -Boolean CExpr_CanImplicitlyConvert(ENode *expr, Type *type2, UInt32 qual2) { - ImplicitConv result; - return CExpr_ImplicitConversionMatch(expr, type2, qual2, &result); -} - -static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean nullcheckflag, Boolean pathcheckflag) { - BClassList *path; - short depth; - Boolean isambigbase; - - if ( - IS_TYPE_CLASS(type2) && - IS_TYPE_CLASS(expr->rtype) && - (path = CClass_GetBasePath(TYPE_CLASS(expr->rtype), TYPE_CLASS(type2), &depth, &isambigbase)) - ) - { - if (isambigbase) - CError_Error(CErrorStr188); - if (flag1) - CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); - - if (pathcheckflag) { - expr = getnodeaddress(expr, 0); - expr = makemonadicnode(CExpr_ClassPointerCast(path, expr, nullcheckflag), EINDIRECT); - expr->rtype = type2; - expr->flags = qual2 & ENODE_FLAG_QUALS; - } - - return expr; - } - else { - return NULL; - } -} - -static ENode *CExpr_ClassReferenceConversion(ENode *expr, Type *type2, UInt32 qual2, Boolean pathcheckflag) { - int refcompat; - - if (CExpr_IsLValue(expr) && IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) { - refcompat = CExpr_IsReferenceCompatible(type2, 0, expr->rtype, 0); - if (refcompat > 0) { - if (refcompat == 2) { - CError_ASSERT(1668, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)); - expr = CExpr_DerivedToBase(expr, type2, qual2, pathcheckflag, 0, 1); - } - expr->flags = qual2 & ENODE_FLAG_QUALS; - return expr; - } - - refcompat = CExpr_IsReferenceCompatible(expr->rtype, 0, type2, 0); - if (refcompat > 0) { - expr = CClass_ClassPointerCast( - getnodeaddress(expr, 0), - TYPE_CLASS(expr->rtype), TYPE_CLASS(type2), - 1, 1, pathcheckflag - ); - CError_ASSERT(1680, IS_TYPE_POINTER_ONLY(expr->rtype)); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = type2; - expr->flags = qual2 & ENODE_FLAG_QUALS; - return expr; - } - } - - if (IS_TYPE_CLASS(expr->rtype)) { - if ((expr = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1))) - return expr; - } - - return NULL; -} - -static ENode *CExpr_BindToReference(ENode *expr, Type *type2, UInt32 qual2) { - UInt32 cv; - int refcompat; - ENode *tmp; - - cv = CParser_GetCVTypeQualifiers(type2, qual2); - - if (CExpr_IsLValue(expr)) { - refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr)); - if (refcompat > 0) { - if (refcompat == 2) { - CError_ASSERT(1718, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)); - expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1); - } - return getnodeaddress(expr, 0); - } - } else if (IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) { - refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr)); - if (refcompat > 0) { - if (refcompat == 2) - expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1); - return getnodeaddress(expr, 0); - } - } - - if (IS_TYPE_CLASS(expr->rtype)) { - if ((tmp = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1))) - return getnodeaddress(tmp, 0); - } - - if (!(cv & Q_CONST)) - CError_Error(CErrorStr228); - if (cv & Q_VOLATILE) - CError_Error(CErrorStr259); - - if (expr->rtype != type2) - expr = CExpr_Convert(expr, type2, qual2, 0, 1); - - if (!CExpr_IsLValue(expr)) { - expr = CExpr_LValue(expr, 0, 0); - if (!ENODE_IS(expr, EINDIRECT)) - expr = get_address_of_temp_copy(expr, 1); - else - expr = getnodeaddress(expr, 0); - } else { - expr = getnodeaddress(expr, 0); - } - - return expr; -} - -ENode *CExpr_Convert(ENode *expr, Type *type, UInt32 qual, Boolean isExplicit, Boolean flag2) { - UInt32 cv; - ENode *refExpr; - ENode *newExpr; - Type *typeCopy; - NameSpaceObjectList myList; - - cv = qual & Q_CV; - - if (copts.cpp_extensions && is_typesame(expr->rtype, type) && !ENODE_IS(expr, EOBJLIST)) { - expr = CExpr_RewriteConst(expr); - expr->rtype = type; - expr->flags &= ~ENODE_FLAG_QUALS; - expr->flags |= cv; - return expr; - } - - if (type == TYPE(&stvoid)) { - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - } - - if (IS_TYPE_REFERENCE(type)) { - if (isExplicit) { - refExpr = CExpr_ClassReferenceConversion(expr, TPTR_TARGET(type), qual, flag2); - if (refExpr) - return refExpr; - - expr = getnodeaddress(expr, 0); - typeCopy = galloc(sizeof(TypePointer)); - *TYPE_POINTER(typeCopy) = *TYPE_POINTER(type); - TPTR_QUAL(typeCopy) &= ~Q_REFERENCE; - expr = CExpr_Convert(expr, typeCopy, qual, 0, flag2); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TPTR_TARGET(type); - expr->flags = cv; - return expr; - } else { - return CExpr_BindToReference(expr, TPTR_TARGET(type), qual); - } - } - - if ( - (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type)) || - (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type)) - ) - { - expr = pointer_generation(expr); - } else { - expr = CExpr_RewriteConst(expr); - } - - if (ENODE_IS(expr, EOBJLIST)) { - if (CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type, &refExpr)) - return refExpr; - } else if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) { - myList.next = NULL; - myList.object = OBJ_BASE(expr->data.objref); - if (CExpr_OverloadFuncMatch(&myList, NULL, type, &refExpr)) - return refExpr; - } else if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type)) { - if (expr->rtype->size == 0) - CDecl_CompleteType(expr->rtype); - - if (IS_TYPE_CLASS(type)) { - CanAllocObject(type); - if (!CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_IsTrivialCopyClass(TYPE_CLASS(type))) { - if (expr->rtype == type) - return expr; - - refExpr = CExpr_DerivedToBase(expr, type, qual, flag2, 0, 1); - if (refExpr) - return refExpr; - } - } - - refExpr = CExpr_UserConversion(expr, type, qual, NULL, 1, isExplicit, 0); - if (refExpr) { - refExpr->flags = cv; - return refExpr; - } - } else if (!isExplicit && is_typesame(expr->rtype, type)) { - if (ENODE_IS(expr, EINDIRECT) && ENODE_QUALS(expr) != cv) - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - } else { - if ( - copts.warn_implicitconv && - !isExplicit && - IS_TYPE_INT_OR_FLOAT(type) && - IS_TYPE_INT_OR_FLOAT(expr->rtype) - ) - CExpr_CheckArithmConversion(expr, type); - - switch (type->type) { - case TYPEINT: - if (type == TYPE(&stbool)) { - switch (expr->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - return CExpr_ConvertToBool(expr, isExplicit); - } - } else { - switch (expr->rtype->type) { - case TYPEENUM: - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - case TYPEINT: - case TYPEFLOAT: - do_int_float_conversion: - if ( - ENODE_IS(expr, ETYPCON) && - expr->rtype->type == type->type && - expr->rtype->size == type->size && - is_unsigned(expr->rtype) == is_unsigned(type) && - ENODE_QUALS(expr) == qual - ) - { - expr->rtype = type; - expr->flags |= ENODE_FLAG_80; - return expr; - } else { - refExpr = promote(expr, type); - refExpr->flags = cv; - return refExpr; - } - break; - case TYPEPOINTER: - if (expr->rtype->size > type->size && copts.warn_ptr_int_conv) - CError_Warning(CErrorStr382); - if (ENODE_IS(expr, ETYPCON)) { - ENode *inner = expr->data.monadic; - if (ENODE_IS(inner, EINTCONST)) { - inner->rtype = type; - inner->flags = cv; - inner->data.intval = CExpr_IntConstConvert(type, TYPE(&stunsignedlong), inner->data.intval); - return inner; - } - } - if (type->size != 4) { - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = TYPE(&stunsignedlong); - } - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - } - } - break; - - case TYPEFLOAT: - switch (expr->rtype->type) { - case TYPEENUM: - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - case TYPEINT: - case TYPEFLOAT: - goto do_int_float_conversion; - } - break; - - case TYPEENUM: - expr = CExpr_Convert(expr, TYPE_ENUM(type)->enumtype, qual, isExplicit, flag2); - if (!ENODE_IS(expr, EINTCONST)) - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - - case TYPEPOINTER: - switch (expr->rtype->type) { - case TYPEENUM: - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - case TYPEINT: - if (expr->rtype->size != 4) { - if (!ENODE_IS(expr, EINTCONST)) - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = TYPE(&stunsignedlong); - } - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - - case TYPEPOINTER: - if (IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(type))) - expr = CExpr_SafeClassPointerCast(expr, TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), 1, flag2); - if (!ENODE_IS(expr, ETYPCON)) - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - expr->flags = cv; - return expr; - } - break; - - case TYPEMEMBERPOINTER: - if (!IS_TYPE_MEMBERPOINTER(expr->rtype)) - expr = CExpr_MemberPointerConversion(expr, TYPE_MEMBER_POINTER(type), 1); - - if (IS_TYPE_MEMBERPOINTER(expr->rtype)) { - expr = PointerToMemberCast(expr, TYPE_MEMBER_POINTER(expr->rtype), TYPE_MEMBER_POINTER(type), flag2); - expr->flags = cv; - return expr; - } - break; - } - } - - if (isExplicit) { - if ((newExpr = CodeGen_HandleTypeCast(expr, type, qual))) - return newExpr; - } - - CError_Error( - isExplicit ? CErrorStr247 : CErrorStr209, - expr->rtype, ENODE_QUALS(expr), - type, qual); - return nullnode(); -} - -ENode *CExpr_AssignmentPromotion(ENode *expr, Type *type2, UInt32 qual2, Boolean flag) { - ImplicitConv result; - - if (copts.old_argmatch) - return oldassignmentpromotion(expr, type2, qual2, flag); - - if (ENODE_IS(expr, EMEMBER)) - expr = getpointertomemberfunc(expr, type2, 1); - - if (!CExpr_ImplicitConversionMatch(expr, type2, qual2, &result)) { - CError_Error(CErrorStr209, expr->rtype, ENODE_QUALS(expr), type2, qual2); - return nullnode(); - } - - return CExpr_Convert(expr, type2, qual2, 0, flag); -} - -static Boolean CExpr_IsBetterMatch(Match *a, Match *b, int count) { - ImplicitConv *convA; - ImplicitConv *convB; - int i; - Boolean flag; - - convA = a->conv; - convB = b->conv; - flag = 0; - - if (convA->type != ICT_0 && convB->type != ICT_0) { - if (CExpr_IsBetterImplicitConv(convB, convA)) - return 0; - if (CExpr_IsBetterImplicitConv(convA, convB)) - flag = 1; - } - - for (i = 0; i < count; i++) { - if (CExpr_IsBetterImplicitConv(++convB, ++convA)) - return 0; - if (CExpr_IsBetterImplicitConv(convA, convB)) - flag = 1; - } - - if (flag) - return 1; - - if (b->object) { - CError_ASSERT(2165, IS_TYPE_FUNC(b->object->type)); - if (b->object->u.func.inst) { - if (!a->object) - return 1; - - CError_ASSERT(2169, IS_TYPE_FUNC(a->object->type)); - if (!a->object->u.func.inst) - return 1; - - CError_ASSERT(2174, a->specialfunc && b->specialfunc); - if (CTempl_FuncIsMoreSpecialized(a->specialfunc, b->specialfunc)) - return 1; - } - } - - return 0; -} - -static Boolean CExpr_MatchArgs(Object *func, ENodeList *argexprs, ENode *expr, ImplicitConv *convs) { - FuncArg *args; - ENode *newExpr; - Type *type; - - args = TYPE_FUNC(func->type)->args; - - if (!(TYPE_FUNC(func->type)->flags & FUNC_METHOD)) { - convs->type = ICT_0; - } else if (TYPE_METHOD(func->type)->is_static) { - convs->type = ICT_0; - } else if (TYPE_FUNC(func->type)->flags & FUNC_IS_CTOR) { - convs->type = ICT_0; - args = args->next; - } else { - if (!expr) - return 0; - - newExpr = lalloc(sizeof(ENode)); - newExpr->type = EINTCONST; - newExpr->cost = 0; - newExpr->flags = expr->flags; - newExpr->rtype = CDecl_NewPointerType(expr->rtype); - newExpr->data.intval = cint64_zero; - - if (func->datatype == DALIAS) { - CError_ASSERT(2231, func->u.alias.member); - type = CDecl_NewPointerType(func->u.alias.member->type); - } else { - type = args->type; - } - - if (!CExpr_ImplicitConversionMatch(newExpr, type, args->qual, convs)) - return 0; - args = args->next; - } - - convs++; - while (1) { - if (!args || args->type == &stvoid) { - if (argexprs) - return 0; - else - return 1; - } - - if (args == &elipsis || args == &oldstyle) { - while (argexprs) { - convs->type = ICT_1; - argexprs = argexprs->next; - convs++; - } - return 1; - } - - if (!argexprs) - return args->dexpr != NULL; - - if (!CExpr_ImplicitConversionMatch(argexprs->node, args->type, args->qual, convs)) - return 0; - - argexprs = argexprs->next; - args = args->next; - convs++; - } -} - -static Object *CExpr_GetMatchObject(Match *match, HashNameNode *name) { - Object *object; - FuncArg *arg; - TypeFunc *tfunc; - - if (match->object) - return match->object; - - tfunc = lalloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - tfunc->type = TYPEFUNC; - tfunc->functype = &stvoid; - - arg = lalloc(sizeof(FuncArg)); - memclrw(arg, sizeof(FuncArg)); - arg->type = match->type; - arg->qual = match->qual; - tfunc->args = arg; - - if (match->type2) { - arg = lalloc(sizeof(FuncArg)); - memclrw(arg, sizeof(FuncArg)); - arg->type = match->type2; - arg->qual = match->qual2; - tfunc->args->next = arg; - } - - object = lalloc(sizeof(Object)); - memclrw(object, sizeof(Object)); - object->name = name; - object->datatype = DFUNC; - object->nspace = cscope_root; - object->type = TYPE(tfunc); - return object; -} - -static Match *CExpr_FindBestMatch(Match *matches, int count, HashNameNode *name, ObjectList **outList, ENodeList *argExprs) { - Match *scan; - Match *best; - ObjectList *listHead; - ObjectList *list; - - best = matches; - for (scan = matches->next; scan; scan = scan->next) { - if (CExpr_IsBetterMatch(scan, best, count)) - best = scan; - } - - for (scan = matches, listHead = NULL; scan; scan = scan->next) { - if (scan != best && !CExpr_IsBetterMatch(best, scan, count)) { - list = lalloc(sizeof(ObjectList)); - list->next = listHead; - list->object = CExpr_GetMatchObject(scan, name); - listHead = list; - } - } - - if (!outList) { - if (listHead) - CError_OverloadedFunctionError(CExpr_GetMatchObject(best, name), listHead); - } else { - *outList = listHead; - } - - return best; -} - -void CExpr_FuncArgMatch(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match13, ENode *expr, Boolean flag) { - NameSpaceObjectList *i; - NameSpaceObjectList *j; - Match *match; - Match *matches; - Object *object; - Object *object2; - Object *specialfunc; - ENodeList *argscan; - int argcount; - - for (argscan = argexprs, argcount = 0; argscan; argscan = argscan->next) { - CDecl_CompleteType(argscan->node->rtype); - argcount++; - } - - matches = NULL; - match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv))); - - for (i = list; i; i = i->next) { - object = OBJECT(i->object); - if ( - object->otype == OT_OBJECT && - IS_TYPE_FUNC(object->type) && - (!flag || !(object->qual & Q_EXPLICIT)) - ) - { - if (object->datatype == DALIAS && (TYPE_FUNC(object->type)->flags & FUNC_METHOD)) { - for (j = list; j; j = j->next) { - if (j == i) - continue; - - object2 = OBJECT(j->object); - if ( - object2->otype == OT_OBJECT && - IS_TYPE_METHOD(object2->type) && - (TYPE_FUNC(object2->type)->flags & FUNC_FLAGS_CV) == (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_CV) - ) - { - FuncArg *argsA; - FuncArg *argsB; - argsA = TYPE_FUNC(object->type)->args; - if (argsA && !TYPE_METHOD(object->type)->is_static) - argsA = argsA->next; - argsB = TYPE_FUNC(object2->type)->args; - if (argsB && !TYPE_METHOD(object2->type)->is_static) - argsB = argsB->next; - if (is_arglistsame(argsA, argsB)) - break; - } - } - - if (j) - continue; - } - - if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) { - specialfunc = object; - object = CTempl_DeduceFromFunctionCall(object, templargs, argexprs); - if (!object) - continue; - } else { - if (templargs) - continue; - specialfunc = NULL; - } - - if (CExpr_MatchArgs(object, argexprs, expr, match->conv)) { - match->object = object; - match->specialfunc = specialfunc; - match->next = matches; - matches = match; - match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv))); - } - } - } - - if (matches) { - matches = CExpr_FindBestMatch(matches, argcount, NULL, &match13->list, argexprs); - match13->obj = matches->object; - } -} - -static ConversionTypeList *CExpr_BuildConversionTypeList(ENode *expr) { - ConversionTypeList *first; - ConversionTypeList *list; - Object *object; - Type *type; - ConversionIterator convIter; - - if (!IS_TYPE_CLASS(expr->rtype)) { - first = lalloc(sizeof(ConversionTypeList)); - first->next = NULL; - first->func = NULL; - first->type = expr->rtype; - first->qual = ENODE_QUALS(expr); - if (IS_TYPE_ENUM(first->type)) - first->qual = 0; - } else { - first = NULL; - CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype)); - while ((object = CExpr_ConversionIteratorNext(&convIter))) { - type = TYPE_FUNC(object->type)->functype; - if (IS_TYPE_REFERENCE(type)) - type = TPTR_TARGET(type); - - if (!IS_TYPE_CLASS(type)) { - list = lalloc(sizeof(ConversionTypeList)); - list->next = first; - list->func = object; - list->type = type; - list->qual = TYPE_FUNC(object->type)->qual & Q_CV; - first = list; - } - } - } - - return first; -} - -static Type *CExpr_NextPromotedIntegralType(int *p) { - switch (++(*p)) { - case 1: return TYPE(&stsignedint); - case 2: return TYPE(&stunsignedint); - case 3: return TYPE(&stsignedlong); - case 4: return TYPE(&stunsignedlong); - case 5: - if (copts.longlong) - return TYPE(&stsignedlonglong); - else - return NULL; - case 6: - if (copts.longlong) - return TYPE(&stunsignedlonglong); - else - return NULL; - } - - return NULL; -} - -static Type *CExpr_NextArithmeticType(int *p) { - switch (++(*p)) { - case 1: return TYPE(&stbool); - case 2: return TYPE(&stchar); - case 3: return TYPE(&stsignedchar); - case 4: return TYPE(&stunsignedchar); - case 5: return TYPE(&stwchar); - case 6: return TYPE(&stsignedshort); - case 7: return TYPE(&stunsignedshort); - case 8: return TYPE(&stsignedint); - case 9: return TYPE(&stunsignedint); - case 10: return TYPE(&stsignedlong); - case 11: return TYPE(&stunsignedlong); - case 12: return TYPE(&stfloat); - case 13: return TYPE(&stdouble); - case 14: return TYPE(&stlongdouble); - case 15: - if (copts.longlong) - return TYPE(&stsignedlonglong); - else - return NULL; - case 16: - if (copts.longlong) - return TYPE(&stunsignedlonglong); - else - return NULL; - } - - return NULL; -} - -static Type *CExpr_NextPromotedArithmeticType(int *p) { - switch (++(*p)) { - case 1: return TYPE(&stsignedint); - case 2: return TYPE(&stunsignedint); - case 3: return TYPE(&stsignedlong); - case 4: return TYPE(&stunsignedlong); - case 5: return TYPE(&stdouble); - case 6: return TYPE(&stlongdouble); - case 7: - if (copts.longlong) - return TYPE(&stsignedlonglong); - else - return NULL; - case 8: - if (copts.longlong) - return TYPE(&stunsignedlonglong); - else - return NULL; - } - - return NULL; -} - -static Match *CExpr_MatchBuiltin(Match *matches, ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual) { - Match *scan; - Match mymatch; - - if (CExpr_ImplicitConversionMatch(left, leftType, leftQual, &mymatch.conv[0])) { - if (!right || CExpr_ImplicitConversionMatch(right, rightType, rightQual, &mymatch.conv[1])) { - if (right) { - for (scan = matches; scan; scan = scan->next) { - if ( - !scan->object && - is_typesame(scan->type, leftType) && - scan->qual == leftQual && - is_typesame(scan->type2, rightType) && - scan->qual2 == rightQual - ) - return matches; - } - } - - mymatch.next = matches; - mymatch.object = NULL; - mymatch.specialfunc = NULL; - mymatch.type = leftType; - mymatch.qual = leftQual; - mymatch.type2 = rightType; - mymatch.qual2 = rightQual; - - matches = lalloc(sizeof(Match)); - *matches = mymatch; - } - } - - return matches; -} - -static Match *CExpr_CheckIncDecBuiltin(Match *matches, short token, ENode *expr1, ENode *expr2) { - Object *object; - Type *type; - TypeFunc *tfunc; - ConversionIterator convIter; - - if (IS_TYPE_CLASS(expr1->rtype)) { - CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr1->rtype)); - while ((object = CExpr_ConversionIteratorNext(&convIter))) { - tfunc = TYPE_FUNC(object->type); - if (IS_TYPE_REFERENCE(tfunc->functype)) { - type = TPTR_TARGET(tfunc->functype); - switch (type->type) { - case TYPEINT: - if (type == TYPE(&stbool) && token == TK_DECREMENT) - break; - case TYPEFLOAT: - case TYPEPOINTER: - if (!CParser_IsConst(type, tfunc->qual)) { - matches = CExpr_MatchBuiltin( - matches, - expr1, type, tfunc->qual, - expr2, expr2 ? TYPE(&stsignedint) : NULL, 0 - ); - } - break; - } - } - } - } - - return matches; -} - -static Match *CExpr_CheckUnaryBuiltin(Match *matches, short token, ENode *expr) { - ConversionTypeList *typelist; - Type *type; - int typenum; - - switch (token) { - case TK_INCREMENT: - case TK_DECREMENT: - return CExpr_CheckIncDecBuiltin(matches, token, expr, NULL); - - case '!': - matches = CExpr_MatchBuiltin(matches, expr, TYPE(&stbool), 0, NULL, NULL, 0); - break; - - case '~': - typenum = 0; - while ((type = CExpr_NextPromotedIntegralType(&typenum))) { - matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0); - } - break; - - case '*': - case '+': - for (typelist = CExpr_BuildConversionTypeList(expr); typelist; typelist = typelist->next) { - if (IS_TYPE_POINTER_ONLY(typelist->type)) - matches = CExpr_MatchBuiltin(matches, expr, typelist->type, typelist->qual, NULL, NULL, 0); - } - if (token != '+') - break; - - case '-': - typenum = 0; - while ((type = CExpr_NextPromotedArithmeticType(&typenum))) { - matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0); - } - break; - } - - return matches; -} - -static Match *CExpr_CheckBinaryBuiltin(Match *matches, ENode *left, short token, ENode *right) { - int typenum1; - int typenum2; - Type *type1; - Type *type2; - Type *ptrdiff; - Boolean allowPtrDiffOnRight; - Boolean allowPtrCV; - Boolean allowPtrDiffOnLeft; - Boolean allowMemberPtrs; - Boolean allowEnum; - ConversionTypeList *leftList; - ConversionTypeList *rightList; - ConversionTypeList *scan; - - switch (token) { - case TK_INCREMENT: - case TK_DECREMENT: - return CExpr_CheckIncDecBuiltin(matches, token, left, right); - - case '*': - case '+': - case '-': - case '/': - case ':': - case '<': - case '>': - case TK_LOGICAL_EQ: - case TK_LOGICAL_NE: - case TK_LESS_EQUAL: - case TK_GREATER_EQUAL: - typenum1 = 0; - while ((type1 = CExpr_NextPromotedArithmeticType(&typenum1))) { - typenum2 = 0; - while ((type2 = CExpr_NextPromotedArithmeticType(&typenum2))) { - matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0); - } - } - break; - - case '%': - case '&': - case '^': - case '|': - case TK_SHL: - case TK_SHR: - typenum1 = 0; - while ((type1 = CExpr_NextPromotedIntegralType(&typenum1))) { - typenum2 = 0; - while ((type2 = CExpr_NextPromotedIntegralType(&typenum2))) { - matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0); - } - } - return matches; - - case TK_LOGICAL_OR: - case TK_LOGICAL_AND: - return CExpr_MatchBuiltin(matches, left, TYPE(&stbool), 0, right, TYPE(&stbool), 0); - } - - allowEnum = 0; - allowMemberPtrs = 0; - allowPtrCV = 0; - allowPtrDiffOnLeft = 0; - allowPtrDiffOnRight = 0; - - switch (token) { - case '+': - case '[': - allowPtrDiffOnLeft = 1; - allowPtrDiffOnRight = 1; - break; - case '-': - allowPtrCV = 1; - allowPtrDiffOnRight = 1; - break; - case ':': - case TK_LOGICAL_EQ: - case TK_LOGICAL_NE: - allowMemberPtrs = 1; - case '<': - case '>': - case TK_LESS_EQUAL: - case TK_GREATER_EQUAL: - allowPtrCV = 1; - allowEnum = 1; - break; - default: - return matches; - } - - leftList = CExpr_BuildConversionTypeList(left); - rightList = CExpr_BuildConversionTypeList(right); - ptrdiff = CABI_GetPtrDiffTType(); - - for (scan = leftList; ; scan = scan->next) { - if (!scan) { - scan = rightList; - if (!rightList) - break; - rightList = NULL; - } - - type1 = scan->type; - if (IS_TYPE_REFERENCE(type1)) - type1 = TPTR_TARGET(type1); - - switch (type1->type) { - case TYPEENUM: - if (allowEnum) - matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual); - break; - - case TYPEPOINTER: - if (allowPtrDiffOnRight) - matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, ptrdiff, 0); - if (allowPtrDiffOnLeft) - matches = CExpr_MatchBuiltin(matches, left, ptrdiff, 0, right, type1, scan->qual); - if (allowPtrCV) { - if (IS_TYPE_POINTER_ONLY(TPTR_TARGET(type1))) { - type2 = galloc(sizeof(TypePointer)); - *TYPE_POINTER(type2) = *TYPE_POINTER(type1); - TPTR_QUAL(type2) |= Q_CONST | Q_VOLATILE; - matches = CExpr_MatchBuiltin(matches, left, type2, scan->qual, right, type2, scan->qual); - } else { - matches = CExpr_MatchBuiltin(matches, left, type1, Q_CONST | Q_VOLATILE, right, type1, Q_CONST | Q_VOLATILE); - } - } - break; - - case TYPEMEMBERPOINTER: - if (allowMemberPtrs) - matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual); - break; - } - } - - return matches; -} - -static Boolean CExpr_MatchOperands(ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual, ImplicitConv *twoResults, Boolean flag) { - if (flag) { - if (!CExpr_StandardConversionMatch(left, leftType, leftQual, 1, &twoResults[0].u.ic3.standardConv)) - return 0; - twoResults[0].type = ICT_3; - } else { - if (!CExpr_ImplicitConversionMatch(left, leftType, leftQual, &twoResults[0])) - return 0; - } - - if (right) { - if (!CExpr_ImplicitConversionMatch(right, rightType, rightQual, &twoResults[1])) - return 0; - } - - return 1; -} - -Boolean CExpr_CondOperatorMatch(ENode *left, ENode *right, Conversion *conv) { - Match *match; - - if ((match = CExpr_CheckBinaryBuiltin(NULL, left, ':', right))) { - match = CExpr_FindBestMatch(match, 1, GetHashNameNode("operator?:"), NULL, NULL); - CError_ASSERT(2931, !match->object); - - conv->x0 = NULL; - conv->left = CExpr_Convert(left, match->type, match->qual, 0, 1); - conv->right = CExpr_Convert(right, match->type2, match->qual2, 0, 1); - return 1; - } - - return 0; -} - -Boolean CExpr_OperatorMatch(short token, ENode *left, ENode *right, Conversion *conv) { - HashNameNode *name; - ENodeList *argExprs; - BClassList *path; - int hasArg; - Match *matches; - Object *object; - Object *specialfunc; - NameSpaceObjectList *list; - Type *leftType; - UInt32 leftQual; - Type *rightType; - UInt32 rightQual; - NameResult pr; - NameSpaceObjectList myList; - Match myMatch; - - if (!IS_TYPE_CLASS(left->rtype)) { - if (!IS_TYPE_ENUM(left->rtype)) { - if (!right || !(IS_TYPE_CLASS(right->rtype) || IS_TYPE_ENUM(right->rtype))) - return 0; - } - } else { - CDecl_CompleteType(left->rtype); - } - - name = CMangler_OperatorName(token); - path = NULL; - - argExprs = lalloc(sizeof(ENodeList)); - argExprs->node = left; - if (right) { - argExprs->next = lalloc(sizeof(ENodeList)); - argExprs->next->node = right; - argExprs->next->next = NULL; - hasArg = 1; - } else { - argExprs->next = NULL; - hasArg = 0; - } - - matches = NULL; - - if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr, name)) { - if (token != '=' || (pr.bcl_18->type == left->rtype && !pr.bcl_18->next)) { - if (pr.obj_10) { - myList.next = NULL; - myList.object = pr.obj_10; - pr.nsol_14 = &myList; - } else { - CError_ASSERT(3009, pr.nsol_14); - } - - for (list = pr.nsol_14; list; list = list->next) { - object = OBJECT(list->object); - if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { - if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) { - specialfunc = object; - object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs->next); - if (!object) - continue; - } else { - specialfunc = NULL; - } - - leftType = CExpr_GetImplictObjectParamType(object, &leftQual); - if (right) { - if (!CExpr_HasNParams(object, 1)) - continue; - rightType = CExpr_GetParamType(object, 0, &rightQual); - } else { - if (!CExpr_HasNParams(object, 0)) - continue; - } - - if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 1)) { - myMatch.object = object; - myMatch.specialfunc = specialfunc; - myMatch.next = matches; - matches = lalloc(sizeof(Match)); - *matches = myMatch; - path = pr.bcl_18; - } - } - } - } - } - - if (CScope_FindNonClassObject(cscope_current, &pr, name)) { - if (pr.obj_10) { - myList.next = NULL; - myList.object = pr.obj_10; - pr.nsol_14 = &myList; - } - } else { - pr.nsol_14 = NULL; - } - - if (copts.arg_dep_lookup) - pr.nsol_14 = CScope_ArgumentDependentNameLookup(pr.nsol_14, name, argExprs, 1); - - for (list = pr.nsol_14; list; list = list->next) { - object = OBJECT(list->object); - if (object->otype == OT_OBJECT && IS_TYPE_NONMETHOD(object->type)) { - if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) { - specialfunc = object; - object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs); - if (!object) - continue; - } else { - specialfunc = NULL; - } - - leftType = CExpr_GetParamType(object, 0, &leftQual); - if (right) { - if (!CExpr_HasNParams(object, 2)) - continue; - rightType = CExpr_GetParamType(object, 1, &rightQual); - } else { - if (!CExpr_HasNParams(object, 1)) - continue; - } - - if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 0)) { - myMatch.object = object; - myMatch.specialfunc = specialfunc; - myMatch.next = matches; - matches = lalloc(sizeof(Match)); - *matches = myMatch; - } - } - } - - if (right) - matches = CExpr_CheckBinaryBuiltin(matches, left, token, right); - else - matches = CExpr_CheckUnaryBuiltin(matches, token, left); - - if (matches) { - conv->x0 = NULL; - conv->left = NULL; - conv->right = NULL; - - matches = CExpr_FindBestMatch(matches, hasArg, name, NULL, argExprs); - object = matches->object; - if (!object) { - if (IS_TYPE_CLASS(left->rtype)) - conv->left = CExpr_Convert(left, matches->type, matches->qual, 0, 1); - else - conv->left = left; - - if (right) { - if (IS_TYPE_CLASS(right->rtype)) - conv->right = CExpr_Convert(right, matches->type2, matches->qual2, 0, 1); - else - conv->right = right; - } - - return 1; - } - - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) { - CError_ASSERT(3125, path); - left = CExpr_GenericFuncCall(path, argExprs->node, 0, object, NULL, NULL, argExprs->next, 0, 0, 1); - } else { - left = CExpr_GenericFuncCall(NULL, NULL, 0, object, NULL, NULL, argExprs, 0, 0, 1); - } - - conv->x0 = checkreference(left); - return 1; - } - - return 0; -} - -static ENode *CExpr_ClassCopyInit(TypeClass *tclass, ENode *expr1, ENode *expr2) { - Object *best; - NameSpaceObjectList *list; - ObjectList *objlist; - ObjectList *objlistEntry; - ENodeList *argExprs; - FuncArg *arg; - Type *type; - Object *object; - ImplicitConv bestConv; - ImplicitConv conv; - BClassList path; - ConversionIterator convIter; - - best = NULL; - objlist = NULL; - - for (list = CClass_Constructor(tclass); list; list = list->next) { - object = OBJECT(list->object); - if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type) && !(object->qual & Q_EXPLICIT)) { - arg = TYPE_FUNC(object->type)->args; - - CError_ASSERT(3199, arg); - arg = arg->next; - - if (tclass->flags & CLASS_HAS_VBASES) { - CError_ASSERT(3203, arg); - arg = arg->next; - } - - if ( - arg && - arg != &elipsis && - (!arg->next || arg->next->dexpr) && - CExpr_ImplicitConversionMatch(expr2, arg->type, arg->qual, &conv) - ) - { - if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) { - best = object; - bestConv = conv; - objlist = NULL; - } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) { - objlistEntry = lalloc(sizeof(ObjectList)); - objlistEntry->next = objlist; - objlistEntry->object = object; - objlist = objlistEntry; - } - } - } - } - - if (IS_TYPE_CLASS(expr2->rtype)) { - CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr2->rtype)); - while ((object = CExpr_ConversionIteratorNext(&convIter))) { - type = TYPE_FUNC(object->type)->functype; - if (IS_TYPE_REFERENCE(type)) - type = TPTR_TARGET(type); - - if ( - IS_TYPE_CLASS(type) && - (tclass == TYPE_CLASS(type) || CClass_IsBaseClass(tclass, TYPE_CLASS(type), NULL, 0, 0)) - ) - { - CError_ASSERT(3248, TYPE_FUNC(object->type)->args && - IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->args->type)); - - type = galloc(sizeof(TypePointer)); - *TYPE_POINTER(type) = *TYPE_POINTER(TYPE_FUNC(object->type)->args->type); - TPTR_QUAL(type) = Q_REFERENCE; - if (CExpr_ImplicitConversionMatch(expr2, type, TYPE_FUNC(object->type)->args->qual, &conv)) { - if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) { - best = object; - bestConv = conv; - objlist = NULL; - } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) { - objlistEntry = lalloc(sizeof(ObjectList)); - objlistEntry->next = objlist; - objlistEntry->object = object; - objlist = objlistEntry; - } - } - } - } - } - - if (objlist) - CError_OverloadedFunctionError(best, objlist); - - if (!best) { - CError_Error(CErrorStr209, expr2->rtype, ENODE_QUALS(expr2), tclass, 0); - return expr1; - } - - CError_ASSERT(3284, IS_TYPE_POINTER_ONLY(expr1->rtype)); - - expr1 = makemonadicnode(expr1, EINDIRECT); - expr1->rtype = TYPE(tclass); - - argExprs = lalloc(sizeof(ENodeList)); - argExprs->node = expr2; - if (tclass->flags & CLASS_HAS_VBASES) { - argExprs->next = lalloc(sizeof(ENodeList)); - argExprs->next->next = NULL; - argExprs->next->node = intconstnode(TYPE(&stsignedshort), 1); - } else { - argExprs->next = NULL; - } - - path.next = NULL; - path.type = TYPE(tclass); - expr1 = CExpr_GenericFuncCall(&path, expr1, 0, best, NULL, NULL, argExprs, 0, 0, 1); - - if (ENODE_IS2(expr1, EFUNCCALL, EFUNCCALLP)) - expr1->rtype = CDecl_NewPointerType(TYPE(tclass)); - - expr1 = makemonadicnode(expr1, EINDIRECT); - expr1->rtype = TYPE(tclass); - return expr1; -} |