diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CExpr2.c')
-rw-r--r-- | compiler_and_linker/unsorted/CExpr2.c | 4206 |
1 files changed, 0 insertions, 4206 deletions
diff --git a/compiler_and_linker/unsorted/CExpr2.c b/compiler_and_linker/unsorted/CExpr2.c deleted file mode 100644 index e5c662a..0000000 --- a/compiler_and_linker/unsorted/CExpr2.c +++ /dev/null @@ -1,4206 +0,0 @@ -#include "compiler/CExpr.h" -#include "compiler/CABI.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CInit.h" -#include "compiler/CInt64.h" -#include "compiler/CError.h" -#include "compiler/CFunc.h" -#include "compiler/CInline.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CObjC.h" -#include "compiler/CObjCModern.h" -#include "compiler/CParser.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CScope.h" -#include "compiler/CSOM.h" -#include "compiler/CTemplateFunc.h" -#include "compiler/CTemplateTools.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/enode.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" - -#ifdef __MWERKS__ -#undef va_start -#undef va_arg -#define va_start(ap, parm) ap = __va_start(parm) -#define __va_start(parm) (va_list) (&parm + 1) -//#define va_arg(ap, type) ((((type *) (ap = (va_list) (( ((long) ap + sizeof(type) - 1) & ~(sizeof(type)) ) + sizeof(type) ) ))[-1])) -#define va_arg(ap, type) (*(((type *) (ap = (char *)((((unsigned long)ap + __builtin_align(type) - 1) & ~(__builtin_align(type) - 1) ) + sizeof(type)))) - 1)) -#endif - -ENode *assign_node; -Boolean temp_reference_init; -static SInt32 assign_value; // type? -static ENode *firstarrayexpr; -static Match5 user_std_match; -static Boolean cexpr_hascall; -static Boolean cexpr_esearch_bool[MAXEXPR]; -static Boolean cexpr_rsearch_bool[MAXEXPR]; -static CExprSearchCB cexpr_esearch_callback; -static CExprReplaceCB cexpr_rsearch_callback; -static Type *cexpr_left_conversion_type; -static Type *cexpr_right_conversion_type; - -static FuncArg mon_arg = {NULL, NULL, NULL, NULL, 0, 0, 0, 0}; -static FuncArg diadic_arg2 = {NULL, NULL, NULL, NULL, 0, 0, 0, 0}; -static FuncArg diadic_arg1 = {&diadic_arg1, NULL, NULL, NULL, 0, 0, 0, 0}; - -static void CExpr_RecSearchExprTree(ENode *expr) { - ENodeList *list; - -restart: - if (cexpr_esearch_bool[expr->type]) - cexpr_esearch_callback(expr); - - switch (expr->type) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - expr = expr->data.monadic; - goto restart; - case EMUL: - case EMULV: - case EDIV: - case EMODULO: - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - CExpr_RecSearchExprTree(expr->data.diadic.left); - expr = expr->data.diadic.right; - goto restart; - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ETEMP: - case EARGOBJ: - case ELOCOBJ: - case ELABEL: - case EOBJLIST: - case EMEMBER: - case EINSTRUCTION: - case EVECTOR128CONST: - return; - case EFUNCCALL: - case EFUNCCALLP: - for (list = expr->data.funccall.args; list; list = list->next) - CExpr_RecSearchExprTree(list->node); - expr = expr->data.funccall.funcref; - goto restart; - case ENULLCHECK: - CExpr_RecSearchExprTree(expr->data.nullcheck.nullcheckexpr); - expr = expr->data.nullcheck.condexpr; - goto restart; - case EMFPOINTER: - CExpr_RecSearchExprTree(expr->data.mfpointer.accessnode); - expr = expr->data.mfpointer.mfpointer; - goto restart; - case ECOND: - CExpr_RecSearchExprTree(expr->data.cond.cond); - CExpr_RecSearchExprTree(expr->data.cond.expr1); - expr = expr->data.cond.expr2; - goto restart; - case ENEWEXCEPTION: - case ENEWEXCEPTIONARRAY: - CExpr_RecSearchExprTree(expr->data.newexception.initexpr); - expr = expr->data.newexception.tryexpr; - goto restart; - case EINITTRYCATCH: - if (expr->data.itc.initexpr) - CExpr_RecSearchExprTree(expr->data.itc.initexpr); - if (expr->data.itc.tryexpr) - CExpr_RecSearchExprTree(expr->data.itc.tryexpr); - if (expr->data.itc.catchexpr) - CExpr_RecSearchExprTree(expr->data.itc.catchexpr); - if (expr->data.itc.result) - CExpr_RecSearchExprTree(expr->data.itc.result); - return; - default: - CError_FATAL(128); - } -} - -void CExpr_SearchExprTree(ENode *expr, CExprSearchCB callback, int count, ...) { - va_list ap; - short i; - - cexpr_esearch_callback = callback; - - va_start(ap, count); - for (i = 0; i < MAXEXPR; i++) - cexpr_esearch_bool[i] = 0; - i = 0; - while ((short) i < count) { - cexpr_esearch_bool[va_arg(ap, int)] = 1; - ++i; - } - va_end(ap); - - CExpr_RecSearchExprTree(expr); -} - -static ENode *CExpr_RecSearchExprTreeReplace(ENode *expr) { - ENodeList *list; - ENode *replaced; - - if (cexpr_rsearch_bool[expr->type]) { - replaced = cexpr_rsearch_callback(expr); - if (!replaced) - return expr; - expr = replaced; - } - - switch (expr->type) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - expr->data.monadic = CExpr_RecSearchExprTreeReplace(expr->data.monadic); - return expr; - case EMUL: - case EMULV: - case EDIV: - case EMODULO: - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - expr->data.diadic.left = CExpr_RecSearchExprTreeReplace(expr->data.diadic.left); - expr->data.diadic.right = CExpr_RecSearchExprTreeReplace(expr->data.diadic.right); - return expr; - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EPRECOMP: - case ETEMP: - case EARGOBJ: - case ELOCOBJ: - case ELABEL: - case EMEMBER: - case EINSTRUCTION: - case EVECTOR128CONST: - return expr; - case EFUNCCALL: - case EFUNCCALLP: - for (list = expr->data.funccall.args; list; list = list->next) - list->node = CExpr_RecSearchExprTreeReplace(list->node); - expr->data.funccall.funcref = CExpr_RecSearchExprTreeReplace(expr->data.funccall.funcref); - return expr; - case ENULLCHECK: - expr->data.nullcheck.nullcheckexpr = CExpr_RecSearchExprTreeReplace(expr->data.nullcheck.nullcheckexpr); - expr->data.nullcheck.condexpr = CExpr_RecSearchExprTreeReplace(expr->data.nullcheck.condexpr); - return expr; - case EMFPOINTER: - expr->data.mfpointer.accessnode = CExpr_RecSearchExprTreeReplace(expr->data.mfpointer.accessnode); - expr->data.mfpointer.mfpointer = CExpr_RecSearchExprTreeReplace(expr->data.mfpointer.mfpointer); - return expr; - case ECOND: - expr->data.cond.cond = CExpr_RecSearchExprTreeReplace(expr->data.cond.cond); - expr->data.cond.expr1 = CExpr_RecSearchExprTreeReplace(expr->data.cond.expr1); - expr->data.cond.expr2 = CExpr_RecSearchExprTreeReplace(expr->data.cond.expr2); - return expr; - default: - CError_FATAL(220); - return NULL; - } -} - -ENode *CExpr_SearchExprTreeReplace(ENode *expr, CExprReplaceCB callback, int count, ...) { - va_list ap; - short i; - - cexpr_rsearch_callback = callback; - - va_start(ap, count); - for (i = 0; i < MAXEXPR; i++) - cexpr_rsearch_bool[i] = 0; - i = 0; - while ((short) i < count) { - cexpr_rsearch_bool[va_arg(ap, int)] = 1; - ++i; - } - va_end(ap); - - return CExpr_RecSearchExprTreeReplace(expr); -} - -static void CExpr_HasFuncCallCallBack(ENode *expr) { - cexpr_hascall = 1; -} - -Boolean CExpr_HasFuncCall(ENode *expr) { - cexpr_hascall = 0; - CExpr_SearchExprTree(expr, CExpr_HasFuncCallCallBack, 2, EFUNCCALL, EFUNCCALLP); - return cexpr_hascall; -} - -void CExpr_AliasTransform(ENode *expr) { - ENode *n; - - Object *obj = expr->data.objref; - if (obj->u.alias.offset) { - n = makediadicnode( - create_objectrefnode(obj->u.alias.object), - intconstnode(TYPE(&stunsignedlong), obj->u.alias.offset), - EADD); - *expr = *n; - } else { - expr->data.objref = obj->u.alias.object; - } -} - -ENode *CExpr_UnaryFloatExpression(ENode *expr) { - return expr; -} - -ENode *CExpr_BinaryFloatExpression(ENode *expr) { - return expr; -} - -ENode *CExpr_NewENode(ENodeType ty) { - ENode *expr = lalloc(sizeof(ENode)); - memclrw(expr, sizeof(ENode)); - expr->type = ty; - return expr; -} - -ENode *CExpr_NewTemplDepENode(TemplDepSubType t) { - ENode *expr = CExpr_NewENode(ETEMPLDEP); - expr->rtype = &sttemplexpr; - expr->data.templdep.subtype = t; - return expr; -} - -ENode *nullnode(void) { - ENode *expr = CExpr_NewENode(EINTCONST); - expr->rtype = (Type *) &stsignedlong; - return expr; -} - -ENode *intconstnode(Type *type, SInt32 value) { - ENode *expr = CExpr_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, value); - return expr; -} - -ENode *stringconstnode(char *str) { - ENode *expr; - SInt32 size; - - size = strlen(str) + 1; - expr = CExpr_NewENode(ESTRINGCONST); - expr->rtype = CDecl_NewArrayType((Type *) &stchar, size); - expr->data.string.size = size; - expr->data.string.data = str; - expr->data.string.ispascal = 0; - if (copts.const_strings) - expr->flags = Q_CONST; - - expr = makemonadicnode(expr, EINDIRECT); - expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype); - return expr; -} - -ENode *forceintegral(ENode *expr) { - if (!IS_TYPE_ENUM(expr->rtype)) { - CError_Error(CErrorStr144); - return nullnode(); - } else { - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - return expr; - } -} - -ENode *makemonadicnode(ENode *inner, ENodeType ty) { - ENode *expr = lalloc(sizeof(ENode)); - expr->type = ty; - if ((expr->cost = inner->cost) == 0) - expr->cost = 1; - expr->flags = inner->flags & ENODE_FLAG_QUALS; - expr->rtype = inner->rtype; - expr->data.monadic = inner; - return expr; -} - -ENode *makediadicnode(ENode *left, ENode *right, ENodeType ty) { - ENode *expr = lalloc(sizeof(ENode)); - expr->type = ty; - expr->rtype = left->rtype; - expr->data.diadic.left = left; - expr->data.diadic.right = right; - - if (left->cost != right->cost) { - expr->cost = right->cost; - if (left->cost > expr->cost) - expr->cost = left->cost; - } else { - expr->cost = right->cost + 1; - if (expr->cost > 200) - expr->cost = 200; - } - - expr->flags = (left->flags | right->flags) & ENODE_FLAG_QUALS; - return expr; -} - -ENode *makecommaexpression(ENode *left, ENode *right) { - ENode *expr; - - if (ENODE_IS(right, EINDIRECT) && !ENODE_IS(right->data.monadic, EBITFIELD)) { - Boolean savecpp = copts.cplusplus; - copts.cplusplus = 1; - expr = makediadicnode(left, getnodeaddress(right, 0), ECOMMA); - copts.cplusplus = savecpp; - expr->rtype = expr->data.diadic.right->rtype; - expr = makemonadicnode(expr, EINDIRECT); - } else { - expr = makediadicnode(left, right, ECOMMA); - } - - expr->rtype = right->rtype; - expr->flags = right->flags; - return expr; -} - -short iszero(ENode *expr) { - switch (expr->type) { - case EINTCONST: - return CInt64_IsZero(&expr->data.intval); - case EFLOATCONST: - return CMach_FloatIsZero(expr->data.floatval); - default: - return 0; - } -} - -short isnotzero(ENode *expr) { - Object *obj; - - switch (expr->type) { - case EINTCONST: - return !CInt64_IsZero(&expr->data.intval); - case EFLOATCONST: - return !CMach_FloatIsZero(expr->data.floatval); - case ESTRINGCONST: - case ETEMP: - return 1; - case EOBJREF: - obj = expr->data.objref; - break; - case EADD: - case ESUB: - if (ENODE_IS(expr->data.diadic.left, EOBJREF) && ENODE_IS(expr->data.diadic.right, EINTCONST)) { - obj = expr->data.diadic.left->data.objref; - break; - } - if (ENODE_IS(expr->data.diadic.left, EINTCONST) && ENODE_IS(expr->data.diadic.right, EOBJREF)) { - obj = expr->data.diadic.right->data.objref; - break; - } - return 0; - default: - return 0; - } - - switch (obj->datatype) { - case DLOCAL: - return 1; - default: - return 0; - } -} - -Boolean CExpr_IsOne(ENode *expr) { - if (ENODE_IS(expr, EINTCONST)) - return CInt64_Equal(expr->data.intval, cint64_one); - else if (ENODE_IS(expr, EFLOATCONST)) - return CMach_FloatIsOne(expr->data.floatval); - else - return 0; -} - -Boolean CExpr_AllBitsSet(ENode *expr) { - SInt32 v; - - if (ENODE_IS(expr, EINTCONST)) { - switch (expr->rtype->size) { - case 1: - v = CInt64_GetULong(&expr->data.intval) & 0xFF; - return v == 0xFF; - case 2: - v = CInt64_GetULong(&expr->data.intval) & 0xFFFF; - return v == 0xFFFF; - case 3: - v = CInt64_GetULong(&expr->data.intval) & 0xFFFFFF; - return v == 0xFFFFFF; - case 4: - v = CInt64_GetULong(&expr->data.intval) & 0xFFFFFFFF; - return v == 0xFFFFFFFF; - default: - return CInt64_Equal(expr->data.intval, cint64_negone); - } - } - - return 0; -} - -ENode *CExpr_NewETEMPNode(Type *type, Boolean assign_id) { - ENode *expr = lalloc(sizeof(ENode)); - expr->type = ETEMP; - expr->cost = 0; - expr->flags = 0; - expr->rtype = CDecl_NewPointerType(type); - expr->data.temp.type = type; - expr->data.temp.uniqueid = assign_id ? CParser_GetUniqueID() : 0; - expr->data.temp.needs_dtor = 0; - return expr; -} - -static ENode *CExpr_DerefETEMPCopy(ENode *expr) { - ENode *copy; - - CError_ASSERT(636, IS_TYPE_POINTER_ONLY(expr->rtype)); - - copy = lalloc(sizeof(ENode)); - *copy = *expr; - copy = makemonadicnode(copy, EINDIRECT); - copy->rtype = TYPE_POINTER(copy->rtype)->target; - return copy; -} - -ENode *CExpr_GetETEMPCopy(ENode *expr) { - ENode *newnode; - ENode *assnode; - ENode *finalnode; - - newnode = CExpr_NewETEMPNode(expr->rtype, 1); - newnode->flags = expr->flags; - - assnode = makediadicnode(CExpr_DerefETEMPCopy(newnode), expr, EASS); - assnode->data.diadic.right = lalloc(sizeof(ENode)); - *assnode->data.diadic.right = *expr; - *expr = *assnode; - - finalnode = makemonadicnode(newnode, EINDIRECT); - finalnode->rtype = expr->rtype; - return finalnode; -} - -ENode *integralpromote(ENode *expr) { - if (!IS_TYPE_INT(expr->rtype)) - expr = forceintegral(expr); - - if (TYPE_INTEGRAL(expr->rtype)->integral >= IT_INT) - return expr; - - if (!ENODE_IS(expr, EINTCONST)) - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = (Type *) &stsignedint; - - return expr; -} - -CInt64 CExpr_IntConstConvert(Type *a, Type *b, CInt64 val) { - if (a == (Type *) &stbool) - return CMach_CalcIntDiadic(b, val, TK_LOGICAL_NE, cint64_zero); - else - return CMach_CalcIntDiadic(a, val, '+', cint64_zero); -} - -ENode *promote(ENode *expr, Type *type) { - if (ENODE_IS(expr, EINTCONST)) { - if (IS_TYPE_FLOAT(type)) { - expr->type = EFLOATCONST; - expr->data.floatval = CMach_CalcFloatConvertFromInt(expr->rtype, expr->data.intval); - } else { - expr->data.intval = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval); - } - expr->rtype = type; - return expr; - } - if (ENODE_IS(expr, EFLOATCONST)) { - if (IS_TYPE_FLOAT(type)) { - expr->data.floatval = CMach_CalcFloatConvert(type, expr->data.floatval); - expr->rtype = type; - return expr; - } else if (IS_TYPE_INT(type)) { - expr->data.intval = CMach_CalcIntConvertFromFloat(type, expr->data.floatval); - expr->type = EINTCONST; - expr->rtype = type; - return expr; - } - } - - expr = makemonadicnode(expr, ETYPCON); - expr->rtype = type; - return expr; -} - -void CExpr_ArithmeticConversion(ENode **left, ENode **right) { - switch ((*left)->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - break; - case TYPEENUM: - (*left)->rtype = TYPE_ENUM((*left)->rtype)->enumtype; - break; - default: - CError_Error(CErrorStr144); - (*left) = nullnode(); - } - - switch ((*right)->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - break; - case TYPEENUM: - (*right)->rtype = TYPE_ENUM((*right)->rtype)->enumtype; - break; - default: - CError_Error(CErrorStr144); - (*right) = nullnode(); - } - - if (IS_TYPE_FLOAT((*left)->rtype) || IS_TYPE_FLOAT((*right)->rtype)) { - if ((*left)->rtype != (*right)->rtype) { - if (TYPE_INTEGRAL((*left)->rtype)->integral > TYPE_INTEGRAL((*right)->rtype)->integral) - *right = promote(*right, (*left)->rtype); - else - *left = promote(*left, (*right)->rtype); - } - return; - } - - *left = integralpromote(*left); - *right = integralpromote(*right); - if ((*left)->rtype != (*right)->rtype) { - if (TYPE_INTEGRAL((*left)->rtype)->integral < TYPE_INTEGRAL((*right)->rtype)->integral) { - ENode **tmp = left; - left = right; - right = tmp; - } - - if ((*left)->rtype->size == (*right)->rtype->size && !is_unsigned((*left)->rtype) && is_unsigned((*right)->rtype)) { - if ((*left)->rtype == (Type *) &stsignedlong) { - *left = promote(*left, (Type *) &stunsignedlong); - } else { - CError_ASSERT(838, (*left)->rtype == (Type *) &stsignedlonglong); - *left = promote(*left, (Type *) &stunsignedlonglong); - } - } - - *right = promote(*right, (*left)->rtype); - } -} - -static ENode *CExpr_GetEA(ENode *expr) { - ENode *copy; - - for (;;) { - switch (expr->type) { - case EINDIRECT: - expr = expr->data.monadic; - for (;;) { - switch (expr->type) { - case EOBJREF: - copy = lalloc(sizeof(ENode)); - *copy = *expr; - return copy; - case ECOMMA: - expr = expr->data.diadic.right; - continue; - default: - return CExpr_GetETEMPCopy(expr); - } - } - break; - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - expr = expr->data.monadic; - continue; - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - expr = expr->data.monadic; - continue; - case ECOMMA: - expr = expr->data.diadic.right; - continue; - default: - return NULL; - } - } -} - -ENode *CExpr_TempModifyExpr(ENode *expr) { - Type *type; - ENode *left; - ENode *right; - ENode *eanode; - ENode *tempnode; - ENode *indnode; - ENode *truenode; - - type = expr->rtype; - tempnode = CExpr_NewETEMPNode(type, 1); - eanode = CExpr_GetEA(expr); - if (!eanode) { - CError_Error(CErrorStr142); - return expr; - } - - // tempnode = expr - left = makemonadicnode(tempnode, EINDIRECT); - left->rtype = type; - left = makediadicnode(left, expr, EASS); - - // eanode = true - indnode = makemonadicnode(eanode, EINDIRECT); - indnode->rtype = type; - truenode = nullnode(); - truenode->rtype = (Type *) &stbool; - CInt64_SetLong(&truenode->data.intval, 1); - right = makediadicnode(indnode, truenode, EASS); - - expr = makediadicnode(left, right, ECOMMA); - - indnode = makemonadicnode(tempnode, EINDIRECT); - indnode->rtype = type; - return makediadicnode(expr, indnode, ECOMMA); -} - -Boolean CExpr_IsLValue(ENode *expr) { - while (!ENODE_IS(expr, EINDIRECT)) { - switch (expr->type) { - case EPREINC: - case EPREDEC: - return copts.cplusplus; - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - if (!copts.cplusplus) - return 0; - expr = expr->data.diadic.left; - continue; - case ECOMMA: - if (!copts.cplusplus) - return 0; - expr = expr->data.diadic.right; - continue; - case ECOND: - if ( - copts.cplusplus && - is_typesame(expr->data.cond.expr1->rtype, expr->data.cond.expr2->rtype) && - (expr->data.cond.expr1->rtype->type != TYPEPOINTER || (UInt32) (expr->data.cond.expr1->flags & ENODE_FLAG_QUALS) == (expr->data.cond.expr2->flags & ENODE_FLAG_QUALS)) - ) { - return CExpr_IsLValue(expr->data.cond.expr1) && CExpr_IsLValue(expr->data.cond.expr2); - } - return 0; - default: - return 0; - } - } - - expr = expr->data.monadic; - switch (expr->type) { - case ETEMP: - return 0; - case EFUNCCALL: - if (expr->data.funccall.functype->functype->type != TYPEPOINTER || (expr->data.funccall.functype->flags & FUNC_IS_CTOR)) - return 0; - default: - return 1; - } -} - -ENode *CExpr_LValue(ENode *expr, Boolean flag1, Boolean flag2) { - ENode *eanode; - ENode *tmpnode; - -loop: - switch (expr->type) { - case ETYPCON: - if (copts.pointercast_lvalue || !copts.ANSIstrict) { - if (expr->rtype->type == TYPEPOINTER && expr->data.monadic->rtype->type == TYPEPOINTER) { - switch (expr->data.monadic->type) { - case EINDIRECT: - case ETYPCON: - expr->data.monadic->rtype = expr->rtype; - expr->data.monadic->flags = expr->flags; - expr = expr->data.monadic; - goto loop; - } - } - } - break; - case EINDIRECT: - if (flag2) { - if (!CExpr_IsLValue(expr)) - CError_Warning(CErrorStr142); - - if ( - ENODE_IS(expr->data.monadic, EOBJREF) && - expr->data.monadic->data.objref->name == this_name_node && - cscope_currentfunc && - cscope_currentclass && - expr->data.monadic->data.objref == CClass_ThisSelfObject()) - CError_Error(CErrorStr189); - } - if (flag1) { - if (CParser_IsConst(expr->rtype, expr->flags & ENODE_FLAG_QUALS)) - CError_Error(CErrorStr179); - } - return expr; - case EPREINC: - case EPREDEC: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - if (copts.cplusplus) { - if ((eanode = CExpr_GetEA(expr))) { - tmpnode = makediadicnode(expr, eanode, ECOMMA); - tmpnode->rtype = tmpnode->data.diadic.right->rtype; - tmpnode = makemonadicnode(tmpnode, EINDIRECT); - tmpnode->rtype = expr->rtype; - return tmpnode; - } - CError_Error(CErrorStr190); - return expr; - } - break; - case ECOND: - if ( - copts.cplusplus && - is_typesame(expr->data.cond.expr1->rtype, expr->data.cond.expr2->rtype) && - (expr->data.cond.expr1->rtype->type != TYPEPOINTER || (UInt32) (expr->data.cond.expr1->flags & ENODE_FLAG_QUALS) == (expr->data.cond.expr2->flags & ENODE_FLAG_QUALS)) - ) { - expr->data.cond.expr1 = CExpr_LValue(expr->data.cond.expr1, flag1, flag2); - expr->data.cond.expr2 = CExpr_LValue(expr->data.cond.expr2, flag1, flag2); - if (ENODE_IS(expr->data.cond.expr1, EINDIRECT) && ENODE_IS(expr->data.cond.expr2, EINDIRECT)) { - if (!ENODE_IS(expr->data.cond.expr1->data.monadic, EBITFIELD) && !ENODE_IS(expr->data.cond.expr2->data.monadic, EBITFIELD)) { - expr->data.cond.expr1 = getnodeaddress(expr->data.cond.expr1, 0); - expr->data.cond.expr2 = getnodeaddress(expr->data.cond.expr2, 0); - expr->rtype = expr->data.cond.expr1->rtype; - tmpnode = makemonadicnode(expr, EINDIRECT); - tmpnode->rtype = TYPE_POINTER(tmpnode->rtype)->target; - return tmpnode; - } - } - } - break; - } - - if (flag2) - CError_Error(CErrorStr142); - return expr; -} - -ENode *CExpr_MakeObjRefNode(Object *obj, Boolean flag) { - ENode *expr; - - if (obj->sclass == TK_TYPEDEF) { - CError_Error(CErrorStr141); - return intconstnode((Type *) &void_ptr, 0); - } - - expr = lalloc(sizeof(ENode)); - memclrw(expr, sizeof(ENode)); - expr->type = EOBJREF; - expr->data.objref = obj; - expr->rtype = CDecl_NewPointerType(obj->type); - - if (!IS_TYPE_FUNC(obj->type)) - expr->flags = obj->qual & ENODE_FLAG_QUALS; - if (flag) - obj->flags |= OBJECT_USED; - - return expr; -} - -ENode *create_objectrefnode(Object *obj) { - if (name_obj_check && !name_obj_check(NULL, obj)) - return intconstnode((Type *) &void_ptr, 0); - return CExpr_MakeObjRefNode(obj, 1); -} - -ENode *create_objectnode2(Object *obj) { - ENode *expr; - - if (name_obj_check && !name_obj_check(NULL, obj)) - return nullnode(); - - expr = makemonadicnode(CExpr_MakeObjRefNode(obj, 1), EINDIRECT); - expr->rtype = TYPE_POINTER(expr->rtype)->target; - return expr; -} - -ENode *create_objectnode(Object *obj) { - return checkreference(create_objectnode2(obj)); -} - -static ENode *CExpr_ExpandArg(ENode *expr, Type *type) { - if (ENODE_IS(expr, ETYPCON) && IS_TYPE_FLOAT(type)) { - expr->rtype = type; - return expr; - } else { - return promote(expr, type); - } -} - -ENode *CExpr_IsTempConstruction(ENode *expr, Type *type, ENode **resultexpr) { - ENodeList *args; - ENode *funccall; - ENode *funcref; - - if ( - !ENODE_IS(expr, EINDIRECT) || - expr->rtype != type || - !ENODE_IS((funccall = expr->data.monadic), EFUNCCALL) || - !(args = funccall->data.funccall.args) - ) - return NULL; - - if (!ENODE_IS((funcref = funccall->data.funccall.funcref), EOBJREF) || !CClass_IsConstructor(funcref->data.objref)) { - if (expr->data.monadic->data.funccall.functype->functype != type) - return NULL; - if (CABI_GetStructResultArgumentIndex(expr->data.monadic->data.funccall.functype) == 1) { - args = args->next; - CError_ASSERT(1277, args); - } - } - - if (resultexpr) - *resultexpr = args->node; - return expr->data.monadic; -} - -ENode *CExpr_AdjustFunctionCall(ENode *expr) { - ENodeList *list; - - switch (expr->data.funccall.functype->functype->type) { - case TYPECLASS: - CDecl_CompleteType(expr->data.funccall.functype->functype); - case TYPESTRUCT: - if (!expr->data.funccall.functype->functype->size) - CError_Error(CErrorStr136, expr->data.funccall.functype->functype, 0); - } - - if (CMach_GetFunctionResultClass(expr->data.funccall.functype)) { - list = lalloc(sizeof(ENodeList)); - if (IS_TYPE_CLASS(expr->data.funccall.functype->functype)) { - CDecl_CompleteType(expr->data.funccall.functype->functype); - if (CClass_Destructor(TYPE_CLASS(expr->data.funccall.functype->functype))) - list->node = create_temp_node2(expr->rtype); - else - list->node = create_temp_node(expr->rtype); - } else { - list->node = create_temp_node(expr->rtype); - } - list->next = expr->data.funccall.args; - expr->data.funccall.args = list; - - if (expr->data.funccall.funcref->flags & ENODE_FLAG_10) - expr = CSOM_EnvCheck(expr, list); - - expr = makemonadicnode(expr, EINDIRECT); - expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype); - return expr; - } - - if (expr->data.funccall.funcref->flags & ENODE_FLAG_10) - expr = CSOM_EnvCheck(expr, NULL); - return expr; -} - -ENode *funccallexpr(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, ENode *arg4) { - ENode *expr; - TypeFunc *tfunc; - ENodeList *list; - - tfunc = TYPE_FUNC(func->type); - CError_ASSERT(1411, IS_TYPE_FUNC(tfunc)); - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 4; - expr->rtype = tfunc->functype; - expr->flags = tfunc->qual & ENODE_FLAG_QUALS; - expr->data.funccall.funcref = create_objectrefnode(func); - expr->data.funccall.functype = tfunc; - - if (arg1) { - list = lalloc(sizeof(ENodeList)); - expr->data.funccall.args = list; - list->node = arg1; - if (arg2) { - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg2; - if (arg3) { - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg3; - if (arg4) { - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg4; - } - } - } - list->next = NULL; - } else { - expr->data.funccall.args = NULL; - } - - return CExpr_AdjustFunctionCall(expr); -} - -ENode *CExpr_FuncCallSix(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, ENode *arg4, ENode *arg5, ENode *arg6) { - ENode *expr; - TypeFunc *tfunc; - ENodeList *list; - - tfunc = TYPE_FUNC(func->type); - CError_ASSERT(1460, IS_TYPE_FUNC(tfunc)); - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 4; - expr->rtype = tfunc->functype; - expr->flags = tfunc->qual & ENODE_FLAG_QUALS; - expr->data.funccall.funcref = create_objectrefnode(func); - expr->data.funccall.functype = tfunc; - - list = lalloc(sizeof(ENodeList)); - expr->data.funccall.args = list; - list->node = arg1; - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg2; - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg3; - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg4; - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg5; - if (arg6) { - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = arg6; - } - list->next = NULL; - - return CExpr_AdjustFunctionCall(expr); -} - -static void CExpr_CalcStdAssign(short checkresult, Match5 *match, Type *t1, UInt32 q1, Type *t2, UInt32 q2, Boolean flag) { - memclrw(match, sizeof(Match5)); - switch (checkresult) { - case CheckResult1: - match->x0++; - break; - case CheckResult2: - match->x2++; - break; - case CheckResult3: - match->x4++; - match->x6 += assign_value; - break; - default: - CError_FATAL(1504); - } - - if (flag || (IS_TYPE_POINTER_ONLY(t2) && (IS_TYPE_POINTER_ONLY(t1) || IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(t2))) != 0)) { - if ((q2 & Q_CONST) == (q1 & Q_CONST)) - match->x8++; - if ((q2 & Q_VOLATILE) == (q1 & Q_VOLATILE)) - match->x8++; - } -} - -void CExpr_MatchCV(Type *t1, UInt32 q1, Type *t2, UInt32 q2, Match13 *match) { - Boolean r8; - - if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(t2))) { - t2 = TYPE_POINTER(t2)->target; - r8 = 1; - } else { - r8 = 0; - } - - while (IS_TYPE_POINTER_ONLY(t2) && IS_TYPE_POINTER_ONLY(t1)) { - if (r8) { - if ((TYPE_POINTER(t1)->qual & Q_CONST) != (TYPE_POINTER(t2)->qual & Q_CONST)) - match->anotherm5.x8--; - if ((TYPE_POINTER(t1)->qual & Q_VOLATILE) != (TYPE_POINTER(t2)->qual & Q_VOLATILE)) - match->anotherm5.x8--; - } - t2 = TYPE_POINTER(t2)->target; - t1 = TYPE_POINTER(t1)->target; - r8 = 1; - } - - if ((q1 & Q_CONST) != (q2 & Q_CONST)) - match->anotherm5.x8--; - if ((q1 & Q_VOLATILE) != (q2 & Q_VOLATILE)) - match->anotherm5.x8--; -} - -Boolean CExpr_MatchAssign(Type *type, UInt32 qual, ENode *expr, Match13 *match) { - switch (assign_check(expr, type, qual, 0, 0, 1)) { - case CheckResult0: - return 0; - case CheckResult1: - match->anotherm5.x0++; - break; - case CheckResult2: - match->anotherm5.x2++; - break; - case CheckResult3: - match->anotherm5.x4++; - match->anotherm5.x6 += assign_value; - break; - case CheckResult4: - match->xE++; - match->match5.x0 += user_std_match.x0; - match->match5.x2 += user_std_match.x2; - match->match5.x4 += user_std_match.x4; - match->match5.x6 += user_std_match.x6; - match->match5.x8 += user_std_match.x8; - break; - default: - CError_FATAL(1585); - } - - if (IS_TYPE_POINTER_ONLY(type)) - CExpr_MatchCV(expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, qual, match); - - return 1; -} - -static short CExpr_StdMatchCompare(Match5 *a, Match5 *b, Boolean flag) { - if (a->x0 > b->x0) return 1; - if (a->x0 == b->x0) { - if (a->x2 > b->x2) return 1; - if (a->x2 == b->x2) { - if (a->x4 > b->x4) return 1; - if (a->x4 == b->x4) { - if (a->x6 > b->x6) return 1; - if (a->x6 == b->x6) { - if (!flag) - return 0; - if (a->x8 > b->x8) return 1; - if (a->x8 == b->x8) return 0; - } - } - } - } - return -1; -} - -static short CExpr2_MemberPointerConversion(Type *type, ENode *expr, Boolean flag1) { - ENode *newnode; - short depth; - - newnode = lalloc(sizeof(ENode)); - *newnode = *expr; - if (!IS_TYPE_MEMBERPOINTER(newnode->rtype)) { - newnode = CExpr_MemberPointerConversion(newnode, TYPE_MEMBER_POINTER(type), flag1); - if (iscpp_typeequal(newnode->rtype, type)) { - if (flag1) - assign_node = newnode; - return CheckResult3; - } - } - - if (IS_TYPE_MEMBERPOINTER(newnode->rtype)) { - CError_ASSERT(1656, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2)); - CError_ASSERT(1657, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2)); - - if (CClass_IsBaseClass(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2), &depth, 0, 0)) { - assign_value = 1000 - depth; - if (flag1) - assign_node = PointerToMemberCast(newnode, TYPE_MEMBER_POINTER(newnode->rtype), TYPE_MEMBER_POINTER(type), 1); - return CheckResult3; - } - } - - return CheckResult0; -} - -ENode *CExpr_ClassPointerCast(BClassList *cls, ENode *origexpr, Boolean nullcheckflag) { - ENode *expr; - ClassList *base; - Boolean do_nullcheck; - TypeClass *tclass; - SInt32 offset; - ENode *tmp; - - expr = origexpr; - tclass = TYPE_CLASS(cls->type); - do_nullcheck = 0; - CError_ASSERT(1691, cls); - - if (!IS_TYPE_POINTER_ONLY(origexpr->rtype)) { - CError_Error(CErrorStr141); - return origexpr; - } - - cls = cls->next; - while (cls) { - for (base = tclass->bases; base; base = base->next) { - if (base->base == TYPE_CLASS(cls->type)) - break; - } - - if (!base) { - CError_Error(CErrorStr221); - while (cls->next) - cls = cls->next; - - tmp = nullnode(); - tmp->rtype = CDecl_NewPointerType(cls->type); - return tmp; - } - - if (base->is_virtual) { - if (!base->base->sominfo) { - do_nullcheck = 1; - if ((offset = base->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); - } - } else { - if ((offset = base->offset)) { - do_nullcheck = 1; - if (!canadd(expr, offset)) { - expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); - optimizecomm(expr); - } - } - } - - switch (expr->type) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - expr = makemonadicnode(expr, ETYPCON); - } - - expr->rtype = CDecl_NewPointerType(TYPE(base->base)); - tclass = TYPE_CLASS(cls->type); - cls = cls->next; - } - - if (nullcheckflag && do_nullcheck) - expr = do_castnullcheck(expr, origexpr); - return expr; -} - -ENode *CExpr_GetClassAccessNode(BClassList *a, BClassList *b, ENode *expr, Object *obj, AccessType access, Boolean flag) { - TypeClass *tclass; - ENode *tmp; - - if (!expr) { - if (!cscope_currentfunc || !cscope_currentclass || !cscope_is_member_func || !(expr = CClass_CreateThisSelfExpr())) { - CError_Error(CErrorStr221); - return NULL; - } - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TYPE(cscope_currentclass); - } - - CError_ASSERT(1786, a); - CError_ASSERT(1787, IS_TYPE_CLASS(expr->rtype)); - - tclass = TYPE_CLASS(expr->rtype); - a = CScope_GetClassAccessPath(a, tclass); - if (!a || a->type != TYPE(tclass)) { - CError_Error(CErrorStr221); - return NULL; - } - - if (flag) - CClass_CheckPathAccess(a, obj, access); - - if (!TYPE_CLASS(a->type)->sominfo) { - if (b) - a = CClass_AppendPath(a, b); - - if (!ENODE_IS(expr, EINDIRECT)) - expr = CExpr_LValue(expr, 0, 0); - - if (ENODE_IS(expr, EINDIRECT)) { - expr->data.monadic->flags = expr->flags; - tmp = expr->data.monadic; - switch (tmp->type) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - tmp = makemonadicnode(tmp, ETYPCON); - } - expr = makemonadicnode(CExpr_ClassPointerCast(a, tmp, 0), EINDIRECT); - expr->rtype = TYPE(tclass); - } - } - - return expr; -} - -static short std_assign_check_overload(NameSpaceObjectList *list, TemplArg *templargs, Type *type, Boolean flag1) { - Object *obj; - Object *used_obj; - Boolean found_non_template_func; - Boolean is_ambig; - TemplFuncInstance *instance; - ENode *expr; - Object *cmp1; - Object *cmp2; - - if (!IS_TYPE_POINTER_ONLY(type) || !IS_TYPE_FUNC(TYPE_POINTER(type)->target)) - return CheckResult0; - - used_obj = NULL; - type = TYPE_POINTER(type)->target; - found_non_template_func = 0; - is_ambig = 0; - for (; list; list = list->next) { - obj = OBJECT(list->object); - if (obj->otype != OT_OBJECT) - continue; - - if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) { - if (!found_non_template_func && CTempl_CanDeduceFunc(obj, TYPE_FUNC(type), templargs)) { - instance = CTempl_DeduceFunc(obj, TYPE_FUNC(type), templargs, NULL, 0); - CError_ASSERT(1861, instance); - if (is_typesame(instance->object->type, type)) { - if (used_obj && used_obj != instance->object) - is_ambig = 1; - else - used_obj = instance->object; - } - } - } else { - if (is_typesame(obj->type, type)) { - if (used_obj && found_non_template_func) { - cmp1 = obj; - if (obj->datatype == DALIAS) - cmp1 = obj->u.alias.object; - cmp2 = used_obj; - if (used_obj->datatype == DALIAS) - cmp2 = used_obj->u.alias.object; - if (cmp1 != cmp2) - is_ambig = 1; - } else { - is_ambig = 0; - used_obj = obj; - } - found_non_template_func = 1; - } - } - } - - if (used_obj) { - if (flag1) { - if (is_ambig) - CError_Error(CErrorStr199); - expr = CExpr_MakeObjRefNode(used_obj, 1); - assign_node = expr; - expr->rtype = CDecl_NewPointerType(used_obj->type); - expr->flags = obj->qual & ENODE_FLAG_QUALS; - used_obj->flags |= OBJECT_USED; - if (used_obj->datatype == DINLINEFUNC) - CError_Error(CErrorStr175); - } - return CheckResult1; - } else { - return CheckResult0; - } -} - -ENode *CExpr_ConvertToBool(ENode *expr, Boolean isExplicit) { - if (IS_TYPE_MEMBERPOINTER(expr->rtype)) - expr = CExpr_ConvertToCondition(expr); - - switch (expr->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPEPOINTER: - if (IS_TYPE_ENUM(expr->rtype)) - expr = forceintegral(expr); - switch (expr->type) { - case EINTCONST: - CInt64_SetLong(&expr->data.intval, !CInt64_IsZero(&expr->data.intval)); - break; - case EFLOATCONST: - CInt64_SetLong(&expr->data.intval, !CMach_FloatIsZero(expr->data.floatval)); - expr->type = EINTCONST; - break; - default: - expr = makemonadicnode(expr, ELOGNOT); - expr->rtype = TYPE(&stbool); - expr = makemonadicnode(expr, ELOGNOT); - } - break; - default: - CError_Error( - isExplicit ? CErrorStr247 : CErrorStr209, - expr->rtype, - expr->flags & ENODE_FLAG_QUALS, - &stbool, - 0); - expr = nullnode(); - } - - expr->rtype = TYPE(&stbool); - return expr; -} - -static short std_assign_check(ENode *expr, Type *type, Boolean flag1, Boolean flag2) { - short result; - - if (copts.cplusplus) { - illegalimplicitconversion = 0; - - if ((result = iscpp_typeequal(expr->rtype, type))) { - assign_node = expr; - if (result == -1) { - assign_value = 1; - return CheckResult3; - } else { - return CheckResult1; - } - } - - if (flag1 && illegalimplicitconversion) { - CError_Error(CErrorStr209, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0); - return CheckResult0; - } - } else { - if (is_typeequal(expr->rtype, type)) { - assign_node = expr; - return CheckResult1; - } - } - - if (type == TYPE(&stbool)) { - switch (expr->rtype->type) { - case TYPEPOINTER: - case TYPEMEMBERPOINTER: - assign_value = 0; - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - if (flag1) - assign_node = CExpr_ConvertToBool(expr, 0); - return CheckResult3; - default: - return CheckResult0; - } - } - - if (IS_TYPE_ENUM(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) { - result = CheckResult3; - if (IS_TYPE_INT(type)) { - if (TYPE_ENUM(expr->rtype)->enumtype == type) { - result = CheckResult2; - } else if (TYPE_INTEGRAL(TYPE_ENUM(expr->rtype)->enumtype)->integral < IT_INT) { - switch (TYPE_INTEGRAL(type)->integral) { - case IT_INT: - if (expr->rtype->size < stsignedint.size || TYPE_ENUM(expr->rtype)->enumtype == TYPE(&stsignedshort)) - result = CheckResult2; - break; - case IT_UINT: - if (expr->rtype->size >= stsignedint.size && TYPE_ENUM(expr->rtype)->enumtype != TYPE(&stsignedshort)) - result = CheckResult2; - break; - } - } - } - if (flag1) { - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - assign_node = promote(expr, type); - } - return result; - } - - if (IS_TYPE_INT(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) { - result = CheckResult3; - if (TYPE_INTEGRAL(expr->rtype)->integral <= IT_INT) { - if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint)) { - switch (TYPE_INTEGRAL(type)->integral) { - case IT_INT: - if (expr->rtype->size < stsignedint.size || type != TYPE(&stunsignedshort)) - result = CheckResult2; - break; - case IT_UINT: - if (expr->rtype->size == stsignedint.size && type == TYPE(&stunsignedshort)) - result = CheckResult2; - break; - } - } - } - - if (flag1 && type != expr->rtype) - assign_node = promote(expr, type); - else - assign_node = expr; - return result; - } - - if (IS_TYPE_FLOAT(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) { - if (type == TYPE(&stdouble) && (expr->rtype == TYPE(&stfloat) || expr->rtype == TYPE(&stshortdouble))) - result = CheckResult2; - else - result = CheckResult3; - - if (flag1 && (!IS_TYPE_FLOAT(type) || type->size != expr->rtype->size)) - assign_node = promote(expr, type); - else - assign_node = expr; - return result; - } - - if (IS_TYPE_POINTER_ONLY(type)) { - if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval) && (IS_TYPE_INT(expr->rtype) || (!copts.cplusplus && IS_TYPE_ENUM(expr->rtype)))) { - if (flag1) - expr->rtype = TYPE(&stunsignedlong); - assign_node = expr; - return CheckResult3; - } - if (ENODE_IS(expr, EOBJLIST)) { - return std_assign_check_overload(expr->data.objlist.list, expr->data.objlist.templargs, type, flag1); - } - if (IS_TYPE_POINTER_ONLY(expr->rtype)) { - if (ENODE_IS(expr, EOBJREF) && IS_TYPE_FUNC(expr->data.objref->type) && (TYPE_FUNC(expr->data.objref->type)->flags & FUNC_IS_TEMPL)) { - NameSpaceObjectList list; - list.next = NULL; - list.object = OBJ_BASE(expr->data.objref); - return std_assign_check_overload(&list, NULL, type, flag1); - } - if (copts.objective_c && CObjC_IsCompatibleType(expr->rtype, type)) { - assign_value = 1; - return CheckResult3; - } - if (IS_TYPE_CLASS(TYPE_POINTER(expr->rtype)->target) && IS_TYPE_CLASS(TYPE_POINTER(type)->target)) { - short depth; - Boolean isambig; - BClassList *path; - path = CClass_GetBasePath( - TYPE_CLASS(TYPE_POINTER(expr->rtype)->target), - TYPE_CLASS(TYPE_POINTER(type)->target), - &depth, &isambig - ); - if (path) { - assign_value = 1000 - depth; - if (flag1) { - if (isambig) - CError_Error(CErrorStr188); - if (flag2) - CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); - assign_node = CExpr_ClassPointerCast(path, expr, 1); - } - return CheckResult3; - } else { - if (flag1) { - if (isambig) - CError_Error(CErrorStr188); - else - CError_Error( - CErrorStr244, - expr->rtype, - expr->flags & ENODE_FLAG_QUALS, - type, - 0); - } - return CheckResult0; - } - } - } - } - - if (IS_TYPE_MEMBERPOINTER(type) && !IS_TYPE_CLASS(expr->rtype)) { - return CExpr2_MemberPointerConversion(type, expr, flag1); - } - - if (IS_TYPE_CLASS(expr->rtype) && IS_TYPE_CLASS(type)) { - short depth; - Boolean isambig; - BClassList *path; - path = CClass_GetBasePath( - TYPE_CLASS(expr->rtype), - TYPE_CLASS(type), - &depth, &isambig - ); - if (path) { - assign_value = 1000 - depth; - if (flag1) { - if (isambig) - CError_Error(CErrorStr188); - CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); - assign_node = getnodeaddress(expr, 0); - assign_node = CExpr_ClassPointerCast(path, assign_node, 0); - assign_node = makemonadicnode(assign_node, EINDIRECT); - assign_node->rtype = type; - } - return CheckResult3; - } - } - - if (IS_TYPE_ENUM(type)) { - switch (expr->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - if (!copts.cplusplus) { - if (flag1) { - if (copts.pedantic) - CError_Warning(CErrorStr217, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0); - assign_node = do_typecast(expr, type, 0); - assign_node->flags = expr->flags; - } - return CheckResult2; - } else { - if (flag1) - CError_Error(CErrorStr217, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0); - } - } - } - - return CodeGen_AssignCheck(expr, type, flag1, flag2); -} - -static short is_compatible_conversion(Type *a, Type *b) { - if (IS_TYPE_REFERENCE(a)) - a = TYPE_POINTER(a)->target; - if (IS_TYPE_REFERENCE(b)) - b = TYPE_POINTER(b)->target; - return iscpp_typeequal(b, a); -} - -static void CExpr_ConIteratorInit(ConIterator *iter) { - ClassList *base; - ConIterator *subiter; - ConIteratorList *list; - - for (base = iter->tclass->bases; base; base = base->next) { - if (base->base->flags & CLASS_IS_CONVERTIBLE) { - subiter = galloc(sizeof(ConIterator)); - memclrw(subiter, sizeof(ConIterator)); - subiter->parent = iter; - subiter->tclass = base->base; - CExpr_ConIteratorInit(subiter); - - list = galloc(sizeof(ConIteratorList)); - memclrw(list, sizeof(ConIteratorList)); - list->iter = subiter; - list->next = iter->children; - iter->children = list; - } - } -} - -void CExpr_ConversionIteratorInit(ConversionIterator *iter, TypeClass *tclass) { - memclrw(iter, sizeof(ConversionIterator)); - if (tclass->flags & CLASS_IS_CONVERTIBLE) { - iter->coniter = &iter->myconiter; - iter->myconiter.tclass = tclass; - CExpr_ConIteratorInit(&iter->myconiter); - CScope_InitObjectIterator(&iter->objiter, tclass->nspace); - } -} - -static Boolean CExpr_ConversionIteratorIsHidden(ConIterator *iter, TypeFunc *tfunc) { - CScopeObjectIterator objiter; - ObjBase *obj; - TypeFunc *objtfunc; - - while (iter) { - CScope_InitObjectIterator(&objiter, iter->tclass->nspace); - while (1) { - if (!(obj = CScope_NextObjectIteratorObject(&objiter))) - break; - - objtfunc = TYPE_FUNC(OBJECT(obj)->type); - if ( - IS_TYPE_FUNC(objtfunc) && - (objtfunc->flags & FUNC_CONVERSION) && - is_compatible_conversion(tfunc->functype, objtfunc->functype) && - (tfunc->args->qual & Q_CONST) == (objtfunc->args->qual & Q_CONST) && - (tfunc->qual & Q_CONST) == (objtfunc->qual & Q_CONST) - ) - return 1; - } - iter = iter->parent; - } - - return 0; -} - -Object *CExpr_ConversionIteratorNext(ConversionIterator *iter) { - ConIterator *ci; - Object *obj; - - ci = iter->coniter; - if (!ci) - return NULL; - -restart: - if ((obj = OBJECT(CScope_NextObjectIteratorObject(&iter->objiter)))) { - if ( - IS_TYPE_FUNC(obj->type) && - (TYPE_FUNC(obj->type)->flags & FUNC_CONVERSION) && - !CExpr_ConversionIteratorIsHidden(ci->parent, TYPE_FUNC(obj->type)) - ) { - return obj; - } - goto restart; - } - - do { - if (ci->children) { - iter->coniter = ci->children->iter; - ci->children = ci->children->next; - ci = iter->coniter; - CScope_InitObjectIterator(&iter->objiter, ci->tclass->nspace); - goto restart; - } - } while ((ci = ci->parent)); - - return NULL; -} - -short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2, Boolean flag3) { - Object *r26; - ENode *r25; - Boolean r24; - Boolean r23; - Boolean r22; - Type *r18b; - short r18; - TypeFunc *r17; - Object *r17b; - NameSpaceObjectList *r16b; - Object *r16; - Object *r15; - ENode *r15b; - ENode *r14; - short r14b; - TypeFunc *r14c; - ENodeList *r14d; - TypeMemberFunc *r13; - ENodeList *r13b; - short result; - FuncArg *arg; - ConversionIterator iter; - Match5 stdmatch; - Match5 match_8C; - Match5 match_98; - BClassList path; - UInt16 chk; - Boolean is_const, is_volatile; - - CError_ASSERT(2378, copts.old_argmatch); - - memclrw(&stdmatch, sizeof(Match5)); - r24 = 0; - r22 = 0; - r23 = 0; - - if (!type->size) - CDecl_CompleteType(type); - if (!expr->rtype->size) - CDecl_CompleteType(expr->rtype); - - if (IS_TYPE_CLASS(expr->rtype)) { - r18 = 0; - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype)); - while ((r16 = CExpr_ConversionIteratorNext(&iter))) { - r17 = TYPE_FUNC(r16->type); - r14 = CExpr_NewENode(ETEMP); - r14->rtype = r17->functype; - if (IS_TYPE_REFERENCE(r14->rtype)) { - r14->rtype = TYPE_POINTER(r14->rtype)->target; - if (!CParser_IsConst(r14->rtype, r17->qual)) { - r14 = makemonadicnode(r14, EINDIRECT); - r14->data.monadic->rtype = TYPE(&void_ptr); - r14 = makemonadicnode(r14, EINDIRECT); - r14->data.monadic->rtype = TYPE(&void_ptr); - } - } - if ((result = std_assign_check(r14, type, 0, flag3))) { - CExpr_CalcStdAssign(result, &match_98, r17->functype, r17->qual, type, qual, 1); - CError_ASSERT(2419, r17->args && IS_TYPE_POINTER_ONLY(r17->args->type)); - chk = expr->flags; - if (!(is_const = (r17->args->qual & Q_CONST)) && (chk & Q_CONST) != 0) - continue; - if (!(is_volatile = (r17->args->qual & Q_VOLATILE)) && (chk & Q_VOLATILE) != 0) - continue; - //if (((r17->args->qual & Q_CONST) == 0 && (chk & Q_CONST) != 0) || ((r17->args->qual & Q_VOLATILE) == 0 && (chk & Q_VOLATILE) != 0)) - // continue; - - r14b = 0; - if (is_const == (expr->flags & Q_CONST)) - r14b++; - if (is_volatile == (expr->flags & Q_VOLATILE)) - r14b++; - switch (CExpr_StdMatchCompare(&match_98, &stdmatch, 1)) { - case -1: - continue; - case 0: - if (r26 == r16) - continue; - if (r14b < r18) - continue; - if (r14b != r18) - break; - r22 = 1; - continue; - } - r26 = r16; - stdmatch = match_98; - r24 = 1; - r22 = 0; - r18 = r14b; - } - } - } - - if (IS_TYPE_CLASS(type) && (r16b = CClass_Constructor(TYPE_CLASS(type)))) { - memclrw(&match_8C, sizeof(Match5)); - for (; r16b; r16b = r16b->next) { - r17b = OBJECT(r16b->object); - if (r17b->otype != OT_OBJECT) - continue; - r14c = TYPE_FUNC(r17b->type); - if (!IS_TYPE_FUNC(r14c)) - continue; - if (!flag2 && (r14c->qual & Q_EXPLICIT)) - continue; - if (!r14c->args) - continue; - if (!(arg = r14c->args->next)) - continue; - if ((TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) && !(arg = arg->next)) - continue; - if (arg == &elipsis) - continue; - if (arg->next && !arg->next->dexpr && arg->next != &elipsis) - continue; - - r18b = arg->type; - if (IS_TYPE_REFERENCE(r18b)) { - r18b = TYPE_POINTER(r18b)->target; - if (!CParser_IsConst(r18b, arg->qual) && !CExpr_IsLValue(expr)) - continue; - } - - if ((result = std_assign_check(expr, r18b, 0, flag3))) { - CExpr_CalcStdAssign(result, &match_98, r14c->functype, r14c->qual, type, qual, 0); - switch (CExpr_StdMatchCompare(&match_98, &match_8C, 1)) { - case -1: - case 0: - continue; - } - r25 = expr; - match_8C = match_98; - r23 = 1; - r15 = r17b; - } - } - - if (r23) { - if (r24) { - switch (CExpr_StdMatchCompare(&stdmatch, &match_8C, 1)) { - case -1: - stdmatch = match_8C; - r24 = 0; - break; - case 0: - r22 = 1; - break; - } - } else { - stdmatch = match_8C; - } - } - } - - if (r22 && flag1) - CError_Error(CErrorStr199); - - if (r24 || r23) { - if (flag1) { - if (r24) { - r13 = TYPE_METHOD(r26->type); - CError_ASSERT(2537, r13->flags & FUNC_METHOD); - r15b = create_objectrefnode(r26); - r26->flags |= OBJECT_USED; - r14d = lalloc(sizeof(ENodeList)); - r14d->next = NULL; - expr = getnodeaddress(expr, 0); - r14d->node = CExpr_AssignmentPromotion(expr, CDecl_NewPointerType(TYPE(r13->theclass)), expr->flags, 0); - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 4; - expr->rtype = r13->functype; - expr->flags = r13->qual & ENODE_FLAG_QUALS; - expr->data.funccall.funcref = r15b; - expr->data.funccall.args = r14d; - expr->data.funccall.functype = TYPE_FUNC(r26->type); - assign_node = checkreference(CExpr_AdjustFunctionCall(expr)); - if (assign_node->rtype != type) - assign_node = CExpr_AssignmentPromotion(assign_node, type, qual, 1); - if (!IS_TYPE_REFERENCE(r13->functype)) - temp_reference_init = 1; - } else { - r13b = lalloc(sizeof(ENodeList)); - r13b->next = NULL; - r13b->node = r25; - if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) { - r13b->next = lalloc(sizeof(ENodeList)); - r13b->next->node = r25; - r13b->next->next = NULL; - r13b->node = intconstnode(TYPE(&stsignedshort), 1); - } - path.next = NULL; - path.type = type; - assign_node = makemonadicnode(create_temp_node(type), EINDIRECT); - assign_node->rtype = type; - assign_node = CExpr_GenericFuncCall(&path, assign_node, 0, r15, NULL, NULL, r13b, 0, 0, 1); - if (ENODE_IS2(assign_node, EFUNCCALL, EFUNCCALLP)) { - assign_node->rtype = CDecl_NewPointerType(type); - assign_node = makemonadicnode(assign_node, EINDIRECT); - assign_node->rtype = type; - } - temp_reference_init = 1; - } - } - - user_std_match = stdmatch; - return CheckResult4; - } else { - if (flag1) - CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, qual); - return CheckResult0; - } -} - -ENode *CExpr_ConvertToCondition(ENode *expr) { - switch (expr->rtype->type) { - case TYPEINT: - case TYPEFLOAT: - case TYPEPOINTER: - return expr; - case TYPEENUM: - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - return expr; - case TYPEMEMBERPOINTER: - return memberpointercompare(ENOTEQU, expr, nullnode()); - case TYPECLASS: - return CExpr_Convert(expr, TYPE(&stbool), 0, 0, 1); - default: - CError_Error(CErrorStr376, expr->rtype, expr->flags & ENODE_FLAG_QUALS); - return nullnode(); - } -} - -ENode *CExpr_ConvertToIntegral(ENode *expr) { - ConversionIterator iter; - Type *found; - Object *obj; - - switch (expr->rtype->type) { - case TYPEINT: - case TYPEENUM: - return integralpromote(expr); - case TYPECLASS: - CDecl_CompleteType(expr->rtype); - found = NULL; - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (IS_TYPE_INT_OR_ENUM(TYPE_FUNC(obj->type)->functype)) { - if (found) { - CError_Error(CErrorStr199); - break; - } - found = TYPE_FUNC(obj->type)->functype; - } - } - if (found) - return integralpromote(CExpr_Convert(expr, found, 0, 0, 1)); - break; - } - - CError_Error(CErrorStr376, expr->rtype, expr->flags & ENODE_FLAG_QUALS); - return nullnode(); -} - -void CExpr_CheckArithmConversion(ENode *expr, Type *type) { - CInt64 val; - - if (expr->rtype == type) - return; - if (expr->rtype == TYPE(&stbool)) - return; - - if (IS_TYPE_INT(expr->rtype)) { - if (IS_TYPE_FLOAT(type)) - return; - CError_ASSERT(2772, IS_TYPE_INT(type)); - - if (type->size > expr->rtype->size) - return; - if (type->size == expr->rtype->size && is_unsigned(type) == is_unsigned(expr->rtype)) - return; - - switch (expr->type) { - case EINTCONST: - if (!CInt64_IsNegative(&expr->data.intval) || is_unsigned(expr->rtype) || !is_unsigned(type)) { - val = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval); - val = CExpr_IntConstConvert(expr->rtype, type, val); - if (CInt64_Equal(val, expr->data.intval)) - return; - } - break; - case ELOGNOT: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case ELAND: - case ELOR: - return; - } - } else { - if (IS_TYPE_FLOAT(type) && type->size >= expr->rtype->size) - return; - } - - CError_Warning(CErrorStr317, expr->rtype, 0, type, 0); -} - -ENode *get_address_of_temp_copy(ENode *expr, Boolean flag) { - char buf[64]; - ENode *result; - Object *obj; - Type *innertype; - - if (flag) { - if (ENODE_IS2(expr, EINTCONST, EFLOATCONST)) { - obj = CParser_NewCompilerDefDataObject(); - obj->type = expr->rtype; - obj->name = CParser_GetUniqueName(); - obj->sclass = TK_STATIC; - if (ENODE_IS(expr, EINTCONST)) { - innertype = expr->rtype; - switch (innertype->type) { - case TYPEINT: - break; - case TYPEENUM: - innertype = TYPE_ENUM(innertype)->enumtype; - break; - case TYPEPOINTER: - innertype = TYPE(&stunsignedlong); - break; - default: - CError_FATAL(2857); - } - CMach_InitIntMem(innertype, expr->data.intval, buf); - } else { - CMach_InitFloatMem(expr->rtype, expr->data.floatval, buf); - } - CInit_DeclareData(obj, buf, NULL, obj->type->size); - return create_objectrefnode(obj); - } - - if (cinit_tempnodefunc == NULL) - result = CExpr_NewETEMPNode(expr->rtype, 1); - else - result = cinit_tempnodefunc(expr->rtype, 0); - result = makemonadicnode(result, EINDIRECT); - result->rtype = TYPE_POINTER(result->rtype)->target; - return makecommaexpression(makediadicnode(result, expr, EASS), result->data.monadic); - } else { - result = nullnode(); - CInt64_SetLong(&result->data.intval, -1); - result->rtype = CDecl_NewPointerType(expr->rtype); - return result; - } -} - -short assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2, Boolean flag3) { - Type *type2; - Boolean r30; - Boolean r29; - short result; - - assign_value = 1000; - r30 = 0; - r29 = 0; - temp_reference_init = 0; - - type2 = type; - if (IS_TYPE_REFERENCE(type) && !IS_TYPE_FUNC(TYPE_POINTER(type)->target)) { - type2 = TYPE_POINTER(type)->target; - r30 = 1; - } - - assign_node = expr; - if (IS_TYPE_ARRAY(type2)) { - r29 = 1; - type2 = CDecl_NewPointerType(TYPE_POINTER(type2)->target); - } - - if (!type2->size) { - CDecl_CompleteType(type2); - if (!type2->size && !r30) { - if (flag1) { - if (IS_TYPE_CLASS(type2)) - CError_Error(CErrorStr136, type2, 0); - else - CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type2, qual); - } - return CheckResult0; - } - } - - if (copts.warn_implicitconv && flag1 && !flag2) { - if (IS_TYPE_INT_OR_FLOAT(type2) && IS_TYPE_INT_OR_FLOAT(expr->rtype)) - CExpr_CheckArithmConversion(expr, type2); - } - - result = std_assign_check(expr, type2, flag1, flag3); - if (!result) { - if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type2)) { - result = user_assign_check(expr, type2, qual, flag1, flag2, flag3); - } else if (flag1) { - CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type2, qual); - } - } - - if (r30 && result) { - if (flag1) { - if (!ENODE_IS(assign_node, EINDIRECT)) { - if (!r29) { - assign_node = CExpr_LValue(assign_node, 0, 0); - if (!ENODE_IS(assign_node, EINDIRECT)) { - assign_node = get_address_of_temp_copy(assign_node, 1); - temp_reference_init = 1; - } else { - assign_node = getnodeaddress(assign_node, 0); - } - } - } else { - if (!CExpr_IsLValue(assign_node)) - temp_reference_init = 1; - if (!r29) - assign_node = getnodeaddress(assign_node, 0); - } - } else { - if (!r29 && !CExpr_IsLValue(assign_node) && !CParser_IsConst(TYPE_POINTER(type)->target, qual)) { - result = CheckResult0; - } - } - } - - return result; -} - -Boolean CExpr_MatchCompare(Object *obj, Match13 *a, Match13 *b) { - Object *tmp; - ObjectList *list; - - switch (CExpr_StdMatchCompare(&b->anotherm5, &a->anotherm5, 0)) { - case -1: - return 0; - case 0: - if (a->xE > b->xE) - return 0; - if (a->xE != b->xE) - break; - switch (CExpr_StdMatchCompare(&b->match5, &a->match5, 1)) { - case -1: - return 0; - case 0: - if (a->anotherm5.x8 > b->anotherm5.x8) - return 0; - if (a->anotherm5.x8 == b->anotherm5.x8 && (tmp = a->obj)) { - if (tmp->datatype == obj->datatype) { - add_it: - list = lalloc(sizeof(ObjectList)); - list->next = a->list; - a->list = list; - list->object = obj; - return 0; - } - if (obj->datatype == DALIAS) - return 0; - if (tmp->datatype != DALIAS) - goto add_it; - } - } - } - - *a = *b; - a->obj = obj; - return 1; -} - -static void MatchOverloadFunc(Object *obj, FuncArg *args, ENodeList *argexprs, Match13 *match) { - Match13 match2; - - if (IS_TYPE_FUNC(obj->type) && !(TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) { - memclrw(&match2, sizeof(Match13)); - while (1) { - if (!args || args->type == &stvoid) { - if (!argexprs) - break; - return; - } - - if (args == &elipsis) - break; - if (args == &oldstyle) - break; - - if (!argexprs) { - if (args->dexpr) - break; - return; - } - - if (!CExpr_MatchAssign(args->type, args->qual, argexprs->node, &match2)) - return; - - argexprs = argexprs->next; - args = args->next; - } - - CExpr_MatchCompare(obj, match, &match2); - } -} - -Boolean CExpr_GetFuncMatchArgs(Object *obj, ENodeList *argexprs, ENode *expr, FuncMatchArgs *result) { - ENode *intexpr; - - if (!(TYPE_FUNC(obj->type)->flags & FUNC_METHOD)) { - result->exprs = argexprs; - result->args = TYPE_FUNC(obj->type)->args; - return 1; - } - - if (TYPE_METHOD(obj->type)->is_static) { - result->exprs = argexprs; - result->args = TYPE_FUNC(obj->type)->args; - return 1; - } - - if (TYPE_FUNC(obj->type)->flags & FUNC_IS_CTOR) { - result->exprs = argexprs; - result->args = TYPE_FUNC(obj->type)->args->next; - return 1; - } - - if (expr) { - intexpr = lalloc(sizeof(ENode)); - intexpr->type = EINTCONST; - intexpr->cost = 0; - intexpr->flags = expr->flags; - intexpr->rtype = CDecl_NewPointerType(expr->rtype); - intexpr->data.intval = cint64_zero; - - result->exprs = lalloc(sizeof(ENodeList)); - result->exprs->next = argexprs; - result->exprs->node = intexpr; - - if (obj->datatype == DALIAS) { - result->args = lalloc(sizeof(FuncArg)); - *result->args = *TYPE_FUNC(obj->type)->args; - result->args->type = CDecl_NewPointerType(expr->rtype); - } else { - result->args = TYPE_FUNC(obj->type)->args; - } - - return 1; - } - - return 0; -} - -static NameSpaceObjectList *CExpr_CopyNameSpaceObjectList(NameSpaceObjectList *list) { - NameSpaceObjectList *first; - NameSpaceObjectList *work; - - first = work = lalloc(sizeof(NameSpaceObjectList)); - while (1) { - work->object = list->object; - list = list->next; - if (!list) { - work->next = NULL; - break; - } else { - work->next = lalloc(sizeof(NameSpaceObjectList)); - work = work->next; - } - } - return first; -} - -static void CExpr_MatchArgList(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match, ENode *expr, Boolean flag) { - NameSpaceObjectList *copied_list; - NameSpaceObjectList *scan_list; - Object *obj; - ENodeList *scan_expr; - Boolean is_template; - FuncMatchArgs fma; - - if (!copts.old_argmatch) { - CExpr_FuncArgMatch(CExpr_CopyNameSpaceObjectList(list), templargs, argexprs, match, expr, flag); - return; - } - - copied_list = CExpr_CopyNameSpaceObjectList(list); - - for (scan_expr = argexprs; scan_expr; scan_expr = scan_expr->next) - CDecl_CompleteType(scan_expr->node->rtype); - - scan_list = copied_list; - is_template = 0; - for (; scan_list; scan_list = scan_list->next) { - obj = OBJECT(scan_list->object); - if (obj->otype != OT_OBJECT) - continue; - if (IS_TYPE_FUNC(obj->type) && (!flag || !(obj->qual & Q_EXPLICIT))) { - if (!(TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) { - if (CExpr_GetFuncMatchArgs(obj, argexprs, expr, &fma)) - MatchOverloadFunc(obj, fma.args, fma.exprs, match); - } else { - is_template = 1; - } - } - } - - if (is_template) { - if (!match->obj || match->anotherm5.x2 || match->anotherm5.x4 || match->xE) - CTempl_FuncMatch(copied_list, templargs, argexprs, match, expr); - } -} - -ENode *CExpr_GetDefaultArgument(ENode *funcexpr, FuncArg *arg) { - ENode *tmp; - - if (CTemplTool_IsTemplateArgumentDependentExpression(arg->dexpr)) { - CError_ASSERT(3264, ENODE_IS(funcexpr, EOBJREF)); - tmp = CTemplTool_DeduceDefaultArg( - funcexpr->data.objref, - CInline_CopyExpression(arg->dexpr, CopyMode0) - ); - return argumentpromotion(tmp, arg->type, arg->qual, 1); - } - - return CInline_CopyExpression(arg->dexpr, CopyMode0); -} - -static ENode *CExpr_GenericCall(ENode *funcexpr, ENodeList *argexprs, TypeFunc *tfunc, FuncArg *args) { - ENodeList *list; - ENode *callexpr; - - while (args) { - if (args->dexpr) { - if (argexprs) { - list = argexprs; - while (list->next) - list = list->next; - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - } else { - list = argexprs = lalloc(sizeof(ENodeList)); - } - list->next = NULL; - list->node = CExpr_GetDefaultArgument(funcexpr, args); - } - args = args->next; - } - - callexpr = lalloc(sizeof(ENode)); - callexpr->type = EFUNCCALL; - callexpr->cost = 4; - callexpr->rtype = tfunc->functype; - callexpr->flags = tfunc->qual & ENODE_FLAG_QUALS; - callexpr->data.funccall.funcref = funcexpr; - callexpr->data.funccall.funcref->rtype = CDecl_NewPointerType(TYPE(tfunc)); - callexpr->data.funccall.args = argexprs; - callexpr->data.funccall.functype = tfunc; - funcexpr->data.objref->flags |= OBJECT_USED; - return CExpr_AdjustFunctionCall(callexpr); -} - -static Boolean CExpr_IsObjrefPlusX(ENode *expr) { - Type *type; - - if (ENODE_IS(expr, EOBJREF)) { - type = expr->data.objref->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - return IS_TYPE_CLASS(type); - } - - if (ENODE_IS2(expr, EADD, ESUB)) { - if (CExpr_IsObjrefPlusX(expr->data.diadic.left)) - return 1; - if (CExpr_IsObjrefPlusX(expr->data.diadic.right)) - return 1; - } - - return 0; -} - -static Boolean CExpr_IsStaticType(ENode *expr) { - return ENODE_IS(expr, EINDIRECT) && CExpr_IsObjrefPlusX(expr->data.monadic); -} - -ENode *CExpr_VarArgPromotion(ENode *expr, Boolean flag) { - if (!copts.old_argmatch) - expr = pointer_generation(expr); - - switch (expr->rtype->type) { - case TYPEVOID: - case TYPEFUNC: - CError_Error(CErrorStr353); - expr = nullnode(); - break; - case TYPEINT: - case TYPEENUM: - expr = integralpromote(expr); - break; - case TYPEFLOAT: - if (TYPE_INTEGRAL(expr->rtype)->integral < IT_DOUBLE) - expr = promote(expr, TYPE(&stdouble)); - break; - case TYPECLASS: - expr = classargument(expr); - break; - } - - if (!flag && copts.warn_largeargs) { - if ((IS_TYPE_INT(expr->rtype) && TYPE_INTEGRAL(expr->rtype)->integral >= IT_LONGLONG) || IS_TYPE_FLOAT(expr->rtype)) - CError_Warning(CErrorStr316); - } - - return expr; -} - -ENode *CExpr_GenericFuncCall(BClassList *path, ENode *funcexpr, Boolean flag1, Object *obj, NameSpaceObjectList *nsol, TemplArg *templargs, ENodeList *nodes, Boolean flag2, Boolean flag3, Boolean flag4) { - TypeFunc *tfunc; - AccessType access; - FuncArg *scan_arg; - BClassList *buildpath; - ENode *objexpr; - ENodeList *scan_expr; - BClassList *pathcopy; - Boolean had_alias; - NameSpaceObjectList my_list; - Match13 match; - - memclrw(&match, sizeof(Match13)); - - if (!obj || IS_TEMPL_FUNC(obj->type)) { - if (!funcexpr && cscope_currentfunc && cscope_currentclass && cscope_is_member_func) { - funcexpr = CClass_CreateThisSelfExpr(); - if (funcexpr) { - funcexpr = makemonadicnode(funcexpr, EINDIRECT); - funcexpr->rtype = TYPE(cscope_currentclass); - } - } - - if (obj) { - my_list.next = NULL; - my_list.object = OBJ_BASE(obj); - nsol = &my_list; - } - - CExpr_MatchArgList(nsol, templargs, nodes, &match, funcexpr, flag2); - if (!match.obj) { - CError_ErrorFuncCall(CErrorStr248, nsol, nodes); - return nullnode(); - } - if (match.list) - CError_OverloadedFunctionError(match.obj, match.list); - obj = match.obj; - } - - objexpr = create_objectrefnode(obj); - tfunc = TYPE_FUNC(obj->type); - if (!IS_TYPE_FUNC(tfunc)) { - CError_Error(CErrorStr161); - return nullnode(); - } - - if (IS_TYPEFUNC_METHOD(tfunc) && !TYPE_METHOD(tfunc)->is_static) { - had_alias = 0; - buildpath = NULL; - access = obj->access; - while (obj->datatype == DALIAS) { - buildpath = buildpath ? CClass_AppendPath(buildpath, CClass_GetPathCopy(obj->u.alias.member, 0)) : CClass_GetPathCopy(obj->u.alias.member, 0); - obj = obj->u.alias.object; - objexpr = create_objectrefnode(obj); - had_alias = 1; - } - if (flag3) - CError_Error(CErrorStr188); - - if (TYPE_METHOD(tfunc)->theclass->sominfo && (!(obj->qual & Q_INLINE) || (obj->datatype == DVFUNC && !flag1))) { - pathcopy = CClass_GetPathCopy(path, 0); - funcexpr = CExpr_GetClassAccessNode(path, buildpath, funcexpr, obj, access, flag4); - if (!funcexpr) - return nullnode(); - objexpr = CSOM_MethodAccess(pathcopy, obj, flag1); - } else { - if (obj->datatype == DVFUNC) { - if (flag1 || (!copts.always_vdispatch && !had_alias && funcexpr && CExpr_IsStaticType(funcexpr))) - objexpr->flags |= ENODE_FLAG_80; - } - funcexpr = CExpr_GetClassAccessNode(path, buildpath, funcexpr, obj, access, flag4); - if (!funcexpr) - return nullnode(); - } - - if ( - (tfunc->flags & FUNC_PURE) && - cscope_currentfunc && - (TYPE_FUNC(cscope_currentfunc->type)->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) && - cscope_currentclass == TYPE_METHOD(tfunc)->theclass && - ENODE_IS(funcexpr, EINDIRECT) && - ENODE_IS(funcexpr->data.monadic, EINDIRECT) && - ENODE_IS(funcexpr->data.monadic->data.monadic, EOBJREF) && - funcexpr->data.monadic->data.monadic->data.objref->name == this_name_node && - !(objexpr->flags & ENODE_FLAG_80) - ) - CError_Warning(CErrorStr195); - - scan_expr = lalloc(sizeof(ENodeList)); - scan_expr->next = nodes; - scan_expr->node = funcexpr->data.monadic; - if (ENODE_IS(scan_expr->node, EOBJREF)) - scan_expr->node->data.objref->flags |= OBJECT_FLAGS_2; - - if (((funcexpr->flags & Q_CONST) && !(tfunc->args->qual & Q_CONST)) || ((funcexpr->flags & Q_VOLATILE) && !(tfunc->args->qual & Q_VOLATILE))) { - if (!(tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR))) - CError_Error(CErrorStr236); - } - - nodes = scan_expr; - scan_expr = scan_expr->next; - scan_arg = tfunc->args->next; - } else { - if (flag4 && obj->access != ACCESSPROTECTED) - CClass_CheckObjectAccess(path, obj); - - scan_arg = tfunc->args; - scan_expr = nodes; - if (tfunc->flags & FUNC_METHOD) { - CError_ASSERT(3599, TYPE_METHOD(tfunc)->theclass->sominfo == NULL); - } - } - - while (scan_expr) { - if (scan_arg && scan_arg != &elipsis && scan_arg != &oldstyle) { - scan_expr->node = argumentpromotion(scan_expr->node, scan_arg->type, scan_arg->qual, 1); - scan_arg = scan_arg->next; - } else { - if (!scan_arg) { - my_list.next = NULL; - my_list.object = OBJ_BASE(obj); - CError_ErrorFuncCall(CErrorStr248, &my_list, nodes); - } - scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, scan_arg == &elipsis); - } - scan_expr = scan_expr->next; - } - - if (scan_arg) { - if (scan_arg != &elipsis && scan_arg != &oldstyle) { - if (!scan_arg->dexpr) { - my_list.next = NULL; - my_list.object = OBJ_BASE(obj); - CError_ErrorFuncCall(CErrorStr248, &my_list, nodes); - scan_arg = NULL; - } - } else { - scan_arg = NULL; - } - } - - return CExpr_GenericCall(objexpr, nodes, tfunc, scan_arg); -} - -ENode *CExpr_GenericPtmfCall(Object *obj, TypeFunc *tfunc, ENodeList *arg_exprs) { - ENodeList *scan_expr; - FuncArg *arg; - - scan_expr = arg_exprs; - arg = tfunc->args; - while (scan_expr) { - if (!arg) { - CError_Error(CErrorStr162); - return nullnode(); - } - - if (arg != &elipsis && arg != &oldstyle) { - scan_expr->node = argumentpromotion(scan_expr->node, arg->type, arg->qual, 1); - arg = arg->next; - } else { - scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, arg == &elipsis); - } - scan_expr = scan_expr->next; - } - - if (arg) { - if (arg != &elipsis && arg != &oldstyle) { - if (!arg->dexpr) { - CError_Error(CErrorStr162); - arg = NULL; - } - } else { - arg = NULL; - } - } - - return CExpr_GenericCall(create_objectrefnode(obj), arg_exprs, tfunc, arg); -} - -static ENode *CExpr_ConvertEMember(ENode *expr) { - ENode *result; - - if (expr->data.emember->list->next || expr->data.emember->templargs) { - result = CExpr_NewENode(EOBJLIST); - result->rtype = OBJECT(expr->data.emember->list->object)->type; - result->data.objlist.list = expr->data.emember->list; - result->data.objlist.templargs = expr->data.emember->templargs; - return result; - } - - if (expr->data.emember->list->object->otype != OT_OBJECT) - return NULL; - return CExpr_MakeObjRefNode(OBJECT(expr->data.emember->list->object), 1); -} - -ENode *CExpr_MakeFunctionCall(ENode *funcexpr, ENodeList *arg_exprs) { - ENode *expr; - TypeFunc *tfunc; - BClassList *save_path; - ENode *save_expr; - Boolean save_1D; - Boolean save_isambig; - - FuncArg *scan_arg; - ENodeList *scan_expr; - Boolean has_varargs; - - if (ENODE_IS(funcexpr, EOBJLIST) && funcexpr->data.objlist.name) { - funcexpr->data.objlist.list = CScope_ArgumentDependentNameLookup( - funcexpr->data.objlist.list, - funcexpr->data.objlist.name, - arg_exprs, 0); - if (!funcexpr->data.objlist.list) { - CError_Error(CErrorStr140, CError_GetNameString(NULL, funcexpr->data.objlist.name)); - return nullnode(); - } - - if ( - funcexpr->data.objlist.list->object->otype == OT_OBJECT && - (TYPE_FUNC(OBJECT(funcexpr->data.objlist.list->object)->type)->flags & FUNC_INTRINSIC) && - (expr = CodeGen_HandleIntrinsicCall(OBJECT(funcexpr->data.objlist.list->object), arg_exprs))) - return expr; - - return CExpr_GenericFuncCall( - NULL, NULL, 0, NULL, - funcexpr->data.objlist.list, - funcexpr->data.objlist.templargs, - arg_exprs, 0, 0, 1); - } - - if (ENODE_IS(funcexpr, EMEMBER)) { - save_path = funcexpr->data.emember->path; - save_expr = funcexpr->data.emember->expr; - save_1D = funcexpr->data.emember->pr_1D; - save_isambig = funcexpr->data.emember->isambig; - funcexpr = CExpr_ConvertEMember(funcexpr); - if (!funcexpr) { - CError_Error(CErrorStr161); - return nullnode(); - } - } else { - save_path = NULL; - save_expr = NULL; - save_1D = 0; - save_isambig = 0; - } - - if (ENODE_IS(funcexpr, EOBJREF) && IS_TYPE_FUNC(funcexpr->data.objref->type) && (TYPE_FUNC(funcexpr->data.objref->type)->flags & FUNC_INTRINSIC)) { - if (!(expr = CodeGen_HandleIntrinsicCall(funcexpr->data.objref, arg_exprs))) { - expr = CExpr_GenericFuncCall( - save_path, save_expr, save_1D, funcexpr->data.objref, - NULL, NULL, - arg_exprs, 0, save_isambig, 1); - } - return expr; - } - - if (ENODE_IS(funcexpr, EOBJLIST)) { - return CExpr_GenericFuncCall( - save_path, save_expr, save_1D, NULL, - funcexpr->data.objlist.list, funcexpr->data.objlist.templargs, - arg_exprs, 0, save_isambig, 1); - } - - if (!IS_TYPE_POINTER_ONLY(funcexpr->rtype) || !IS_TYPE_FUNC((tfunc = TYPE_FUNC(TYPE_POINTER(funcexpr->rtype)->target)))) { - CError_Error(CErrorStr161); - return nullnode(); - } - - if (ENODE_IS(funcexpr, EOBJREF)) { - return CExpr_GenericFuncCall( - save_path, save_expr, save_1D, funcexpr->data.objref, - NULL, NULL, arg_exprs, 0, save_isambig, 1); - } - - scan_expr = arg_exprs; // r25 - scan_arg = tfunc->args; // r26 - has_varargs = 0; - while (scan_expr) { - if (!has_varargs) { - if (!scan_arg) { - CError_Error(CErrorStr162); - return nullnode(); - } - if (scan_arg == &elipsis || scan_arg == &oldstyle) { - scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, scan_arg == &elipsis); - has_varargs = 1; - } else { - scan_expr->node = argumentpromotion(scan_expr->node, scan_arg->type, scan_arg->qual, 1); - scan_arg = scan_arg->next; - } - } else { - scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, 0); - } - scan_expr = scan_expr->next; - } - - if (!has_varargs && scan_arg && scan_arg != &elipsis && scan_arg != &oldstyle) { - do { - if (!scan_arg->dexpr) { - CError_Error(CErrorStr162); - return nullnode(); - } - - if (arg_exprs) { - scan_expr = arg_exprs; - while (scan_expr->next) - scan_expr = scan_expr->next; - scan_expr->next = lalloc(sizeof(ENodeList)); - scan_expr = scan_expr->next; - } else { - scan_expr = lalloc(sizeof(ENodeList)); - arg_exprs = scan_expr; - } - - scan_expr->next = NULL; - scan_expr->node = CExpr_GetDefaultArgument(funcexpr, scan_arg); - } while ((scan_arg = scan_arg->next) && scan_arg != &elipsis && scan_arg != &oldstyle); - } - - expr = CExpr_NewENode(EFUNCCALL); - expr->cost = 4; - expr->rtype = tfunc->functype; - expr->flags = tfunc->qual & ENODE_FLAG_QUALS; - expr->data.funccall.funcref = funcexpr; - expr->data.funccall.args = arg_exprs; - expr->data.funccall.functype = tfunc; - return CExpr_AdjustFunctionCall(expr); -} - -static Boolean accept_conversion_type(Type *type, short mode) { - switch (mode) { - case 0: - return IS_TYPE_INT(type); - case 1: - return IS_TYPE_INT_OR_FLOAT(type); - case 2: - return IS_TYPE_INT_OR_FLOAT(type) || IS_TYPE_POINTER_ONLY(type); - case 3: - return IS_TYPE_POINTER_ONLY(type); - default: - CError_FATAL(3912); - return 0; - } -} - -static ENode *CExpr_OperatorConversion(ENode *expr, Type *type, UInt32 qual) { - if (IS_TYPE_CLASS(expr->rtype) && type) { - if (user_assign_check(expr, type, qual, 1, 0, 1)) - return assign_node; - CError_Error(CErrorStr144); - } - return expr; -} - -static Boolean wild_conversion_check(ENode *left, ENode *right, Conversion *conv) { - ConversionIterator iter; - Object *obj; - - Type *check; - Type *left_type; - Type *right_type; - - left_type = right_type = NULL; - if (IS_TYPE_CLASS(left->rtype)) { - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(left->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - check = TYPE_FUNC(obj->type)->functype; - if (accept_conversion_type(check, 2)) { - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, 2)) - CError_Error(CErrorStr199); - } - left_type = check; - goto found_left; - } - } - return 0; - } -found_left: - if (IS_TYPE_CLASS(right->rtype)) { - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(right->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - check = TYPE_FUNC(obj->type)->functype; - if (accept_conversion_type(check, 2)) { - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, 2)) - CError_Error(CErrorStr199); - } - right_type = check; - goto found_right; - } - } - return 0; - } -found_right: - conv->x0 = NULL; - conv->left = CExpr_OperatorConversion(left, left_type, 0); - conv->right = CExpr_OperatorConversion(right, right_type, 0); - return 1; -} - -static Boolean monadic_conversion_check(ENode *expr, short which, Conversion *conv) { - ConversionIterator iter; - Object *obj; - Type *check; - - if (!IS_TYPE_CLASS(expr->rtype)) - return 0; - - if (which == 4) - which = 2; - else if (which == 5) - which = 1; - - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - check = TYPE_FUNC(obj->type)->functype; - if (accept_conversion_type(check, which)) { - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, which)) - CError_Error(CErrorStr199); - } - - conv->x0 = NULL; - conv->left = CExpr_OperatorConversion(expr, check, 0); - conv->right = NULL; - return 1; - } - } - - return 0; -} - -static Boolean is_legal_type_combination(Type *left, Type *right, short mode) { - int left_type; - int right_type; - - if (IS_TYPE_ENUM(left)) - left = TYPE_ENUM(left)->enumtype; - if (IS_TYPE_ENUM(right)) - right = TYPE_ENUM(right)->enumtype; - - if (IS_TYPE_REFERENCE(left)) - left = TYPE_POINTER(left)->target; - if (IS_TYPE_REFERENCE(right)) - right = TYPE_POINTER(right)->target; - - left_type = left->type; // r7 - right_type = right->type; // r8 - switch (mode) { - case 3: - if (left_type != TYPEPOINTER || right_type != TYPEPOINTER) - return 0; - use_cpp_typeequal: - diadic_arg1.type = left; - diadic_arg2.type = right; - return iscpp_typeequal(left, right); - case 7: - if ((left_type == TYPEPOINTER && right_type == TYPEINT) || (left_type == TYPEINT && right_type == TYPEPOINTER)) { - diadic_arg1.type = left; - diadic_arg2.type = right; - return 1; - } - return 0; - case 6: - if ((left_type == TYPEPOINTER && right_type == TYPEINT) || (left_type == TYPEINT && right_type == TYPEPOINTER)) { - diadic_arg1.type = left; - diadic_arg2.type = right; - return 1; - } - case 2: - if (left_type == TYPEPOINTER || right_type == TYPEPOINTER) - goto use_cpp_typeequal; - case 1: - mode1: - if (left_type == TYPEFLOAT || right_type == TYPEFLOAT) { - if (left_type == TYPEFLOAT) { - if (right_type == TYPEFLOAT) { - if (TYPE_INTEGRAL(right)->integral > TYPE_INTEGRAL(left)->integral) - left = right; - diadic_arg2.type = left; - diadic_arg1.type = left; - return 1; - } - if (right_type != TYPEINT) - return 0; - diadic_arg2.type = left; - diadic_arg1.type = left; - return 1; - } - if (left_type != TYPEINT) - return 0; - diadic_arg2.type = right; - diadic_arg1.type = right; - return 1; - } - case 0: - if (left_type != TYPEINT || right_type != TYPEINT) - return 0; - if (TYPE_INTEGRAL(right)->integral > TYPE_INTEGRAL(left)->integral) - left = right; - if (TYPE_INTEGRAL(left)->integral < IT_INT) - left = TYPE(&stsignedint); - diadic_arg2.type = left; - diadic_arg1.type = left; - return 1; - case 4: - if (left_type == TYPEPOINTER) { - if (right_type != TYPEINT) - return 0; - diadic_arg1.type = left; - diadic_arg2.type = right; - return 1; - } - if (right_type == TYPEPOINTER) { - if (left_type != TYPEINT) - return 0; - diadic_arg1.type = left; - diadic_arg2.type = right; - return 1; - } - goto mode1; - case 5: - if (left_type != TYPEPOINTER) - goto mode1; - if (right_type == TYPEPOINTER) - goto use_cpp_typeequal; - if (right_type != TYPEINT) - return 0; - diadic_arg1.type = left; - diadic_arg2.type = right; - return 1; - default: - CError_FATAL(4132); - return 0; - } -} - -static void match_class_type_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) { - ConversionIterator iter; - Object *obj; - - if (which == 6) { - if (!ENODE_IS(right, EINTCONST) || !CInt64_IsZero(&right->data.intval) || !IS_TYPE_INT(right->rtype)) - which = 2; - } - - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(left->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (is_legal_type_combination(TYPE_FUNC(obj->type)->functype, right->rtype, which)) { - MatchOverloadFunc(obj, &diadic_arg1, list, match); - if (match->obj == obj) { - cexpr_left_conversion_type = diadic_arg1.type; - cexpr_right_conversion_type = diadic_arg2.type; - } - } - } -} - -static void match_type_class_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) { - ConversionIterator iter; - Object *obj; - - if (which == 6) { - if (!ENODE_IS(left, EINTCONST) || !CInt64_IsZero(&left->data.intval) || !IS_TYPE_INT(left->rtype)) - which = 2; - } - - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(right->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (is_legal_type_combination(left->rtype, TYPE_FUNC(obj->type)->functype, which)) { - MatchOverloadFunc(obj, &diadic_arg1, list, match); - if (match->obj == obj) { - cexpr_left_conversion_type = diadic_arg1.type; - cexpr_right_conversion_type = diadic_arg2.type; - } - } - } -} - -static void match_class_class_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) { - ConversionIterator iter_left; - ConversionIterator iter_right; - Object *obj_left; - Object *obj_right; - - if (which == 6) - which = 2; - - CExpr_ConversionIteratorInit(&iter_left, TYPE_CLASS(left->rtype)); - while ((obj_left = CExpr_ConversionIteratorNext(&iter_left))) { - CExpr_ConversionIteratorInit(&iter_right, TYPE_CLASS(right->rtype)); - while ((obj_right = CExpr_ConversionIteratorNext(&iter_right))) { - if (is_legal_type_combination(TYPE_FUNC(obj_left->type)->functype, TYPE_FUNC(obj_right->type)->functype, which)) { - MatchOverloadFunc(obj_left, &diadic_arg1, list, match); - if (match->obj == obj_left) { - cexpr_left_conversion_type = diadic_arg1.type; - cexpr_right_conversion_type = diadic_arg2.type; - } - } - } - } -} - -Boolean CExpr_CheckOperatorConversion(short token, ENode *left, ENode *right, ENodeList *list, Conversion *conv) { - Match13 match; - short which; - - switch (token) { - case '*': - if (!right) { - which = 3; - break; - } - case '/': - which = 1; - break; - case '&': - if (!right) - return 0; - case '%': - case '^': - case '|': - case '~': - case TK_SHL: - case TK_SHR: - which = 0; - break; - case '[': - which = 7; - break; - case '+': - which = 4; - break; - case '-': - which = 5; - break; - case '!': - case ':': - case '<': - case '>': - case TK_LESS_EQUAL: - case TK_GREATER_EQUAL: - which = 2; - break; - case TK_LOGICAL_EQ: - case TK_LOGICAL_NE: - which = 6; - break; - case TK_LOGICAL_OR: - case TK_LOGICAL_AND: - return wild_conversion_check(left, right, conv); - default: - return 0; - } - - if (!right) - return monadic_conversion_check(left, which, conv); - - cexpr_left_conversion_type = cexpr_right_conversion_type = NULL; - memclrw(&match, sizeof(Match13)); - - if (IS_TYPE_CLASS(left->rtype)) { - if (IS_TYPE_CLASS(right->rtype)) - match_class_class_conversion(&match, left, right, list, which); - else - match_class_type_conversion(&match, left, right, list, which); - } else { - if (IS_TYPE_CLASS(right->rtype)) - match_type_class_conversion(&match, left, right, list, which); - else - return 0; - } - - if (!match.obj) - return 0; - if (match.list) - CError_OverloadedFunctionError(match.obj, match.list); - - conv->x0 = NULL; - conv->left = CExpr_OperatorConversion(left, cexpr_left_conversion_type, 0); - conv->right = CExpr_OperatorConversion(right, cexpr_right_conversion_type, 0); - return 1; -} - -Boolean CExpr_CheckOperator(short token, ENode *left, ENode *right, Conversion *conv) { - Match13 match; - NameResult pr; - NameResult pr2; - ENode *expr; - Object *obj; - ENodeList *nodes; - HashNameNode *name; - BClassList *path; - EMemberInfo *member; - Object *prev_obj; - NameSpaceObjectList mylist_A8; - NameSpaceObjectList mylist_B0; - - if (!copts.old_argmatch) { - if (token == '(') { - CDecl_CompleteType(left->rtype); - if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr, - CMangler_OperatorName(token))) { - if (pr.nsol_14 || (pr.obj_10 && pr.obj_10->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(pr.obj_10)->type))) { - member = lalloc(sizeof(EMemberInfo)); - memclrw(member, sizeof(EMemberInfo)); - member->path = pr.bcl_18; - member->expr = left; - member->pr_1D = pr.x1D; - if (!pr.nsol_14) { - member->list = galloc(sizeof(NameSpaceObjectList)); - member->list->next = NULL; - member->list->object = pr.obj_10; - } else { - member->list = pr.nsol_14; - } - expr = CExpr_NewENode(EMEMBER); - expr->rtype = &stvoid; - expr->data.emember = member; - tk = lex(); - conv->x0 = checkreference(CExpr_MakeFunctionCall(expr, CExpr_ScanExpressionList(1))); - conv->left = NULL; - conv->right = NULL; - tk = lex(); - return 1; - } else { - CError_FATAL(4371); - } - } - return 0; - } else { - return CExpr_OperatorMatch(token, left, right, conv); - } - } - - if (!IS_TYPE_CLASS(left->rtype)) { - if (!IS_TYPE_ENUM(left->rtype)) { - if (!right) - return 0; - if (!IS_TYPE_CLASS(right->rtype) && !IS_TYPE_ENUM(right->rtype)) - return 0; - } - } else { - CDecl_CompleteType(left->rtype); - } - - memclrw(&match, sizeof(Match13)); - name = CMangler_OperatorName(token); - if (token == '(') { - if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr2, name)) { - if (pr2.nsol_14 || (pr2.obj_10 && pr2.obj_10->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(pr2.obj_10)->type))) { - member = lalloc(sizeof(EMemberInfo)); - memclrw(member, sizeof(EMemberInfo)); - member->path = pr2.bcl_18; - member->expr = left; - member->pr_1D = pr2.x1D; - if (!pr2.nsol_14) { - member->list = galloc(sizeof(NameSpaceObjectList)); - member->list->next = NULL; - member->list->object = pr2.obj_10; - } else { - member->list = pr2.nsol_14; - } - expr = CExpr_NewENode(EMEMBER); - expr->rtype = &stvoid; - expr->data.emember = member; - tk = lex(); - conv->x0 = checkreference(CExpr_MakeFunctionCall(expr, CExpr_ScanExpressionList(1))); - conv->left = NULL; - conv->right = NULL; - tk = lex(); - return 1; - } else { - CError_FATAL(4439); - } - } - return 0; - } - - nodes = lalloc(sizeof(ENodeList)); - nodes->node = left; - if (right) { - nodes->next = lalloc(sizeof(ENodeList)); - nodes->next->node = right; - nodes->next->next = NULL; - } else { - nodes->next = NULL; - } - - obj = NULL; - if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr2, name)) { - if (pr2.obj_10) { - mylist_B0.next = NULL; - mylist_B0.object = pr2.obj_10; - pr2.nsol_14 = &mylist_B0; - } else { - CError_ASSERT(4470, pr2.nsol_14); - } - - if (token != '=' || (pr2.bcl_18->type == left->rtype && pr2.bcl_18->next == NULL)) { - prev_obj = match.obj; - CExpr_MatchArgList(pr2.nsol_14, NULL, nodes->next, &match, left, 0); - if (prev_obj != match.obj) { - obj = match.obj; - path = pr2.bcl_18; - } - } - } - - if (CScope_FindNonClassObject(cscope_current, &pr2, name)) { - if (pr2.obj_10) { - mylist_A8.next = NULL; - mylist_A8.object = pr2.obj_10; - pr2.nsol_14 = &mylist_A8; - } - } else { - pr2.nsol_14 = NULL; - } - - if (copts.arg_dep_lookup) - pr2.nsol_14 = CScope_ArgumentDependentNameLookup(pr2.nsol_14, name, nodes, 1); - if (pr2.nsol_14) - CExpr_MatchArgList(pr2.nsol_14, NULL, nodes, &match, NULL, 0); - - if (!match.obj) { - if (!IS_TYPE_CLASS(left->rtype) && (!right || !IS_TYPE_CLASS(right->rtype))) - return 0; - return CExpr_CheckOperatorConversion(token, left, right, nodes, conv); - } - - if (!(token == '&' && !right) && (token != ',')) { - if (!IS_TYPE_CLASS(left->rtype) && (!right || !IS_TYPE_CLASS(right->rtype)) && match.xE) - return 0; - if (right && match.xE == 2 && CExpr_CheckOperatorConversion(token, left, right, nodes, conv)) - return 1; - } - - if (match.list) - CError_OverloadedFunctionError(match.obj, match.list); - - if (match.obj == obj) { - conv->x0 = CExpr_GenericFuncCall(path, nodes->node, 0, match.obj, NULL, NULL, nodes->next, 0, 0, 1); - } else { - conv->x0 = CExpr_GenericFuncCall(NULL, NULL, 0, match.obj, NULL, NULL, nodes, 0, 0, 1); - } - - conv->x0 = checkreference(conv->x0); - conv->left = NULL; - conv->right = NULL; - return 1; -} - -ENode *CExpr_ConstructObject(TypeClass *tclass, ENode *addr_expr, ENodeList *args, Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4, Boolean flag5) { - ENode *expr; - NameSpaceObjectList *ctorlist; - BClassList path; - - CError_ASSERT(4595, IS_TYPE_POINTER_ONLY(addr_expr->rtype)); - - addr_expr = makemonadicnode(addr_expr, EINDIRECT); - addr_expr->rtype = TYPE(tclass); - - if (!flag3 && args && !args->next && args->node->rtype == TYPE(tclass) && !CClass_CopyConstructor(tclass)) { - CError_ASSERT(4605, IS_TYPE_CLASS(addr_expr->rtype)); - expr = makediadicnode(addr_expr, args->node, EASS); - if (!flag1) - expr = getnodeaddress(expr, 0); - return expr; - } - - if ((ctorlist = CClass_Constructor(tclass))) { - if (tclass->flags & CLASS_HAS_VBASES) { - ENodeList *list = lalloc(sizeof(ENodeList)); - list->next = args; - args = list; - list->node = intconstnode(TYPE(&stsignedshort), flag2 != 0); - } - path.next = NULL; - path.type = TYPE(tclass); - expr = CExpr_GenericFuncCall(&path, addr_expr, 0, NULL, ctorlist, NULL, args, !flag5, 0, flag4); - if (ENODE_IS2(expr, EFUNCCALL, EFUNCCALLP)) - expr->rtype = CDecl_NewPointerType(TYPE(tclass)); - if (flag1) { - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = TYPE(tclass); - } - return expr; - } else { - if (args) { - if (!args->next && ENODE_IS(addr_expr, EINDIRECT)) { - return makediadicnode( - addr_expr, - CExpr_AssignmentPromotion(args->node, TYPE(tclass), 0, 1), - EASS); - } - CError_Error(CErrorStr174); - } - return addr_expr; - } -} - -static ENode *CExpr_DeleteFuncCall(Object *obj, ENode *arg, Type *type, Boolean include_size) { - ENode *expr; - ENodeList *list; - - expr = lalloc(sizeof(ENode)); - expr->type = EFUNCCALL; - expr->cost = 4; - expr->flags = 0; - expr->rtype = &stvoid; - expr->data.funccall.funcref = create_objectrefnode(obj); - expr->data.funccall.functype = TYPE_FUNC(obj->type); - obj->flags |= OBJECT_USED; - - list = lalloc(sizeof(ENodeList)); - list->node = arg; - expr->data.funccall.args = list; - - if (include_size) { - list->next = lalloc(sizeof(ENodeList)); - list->next->node = nullnode(); - CInt64_SetLong(&list->next->node->data.intval, type->size); - list->next->node->rtype = CABI_GetSizeTType(); - list->next->next = NULL; - } else { - list->next = NULL; - } - - return expr; -} - -static ENode *CExpr_CopyPlacementNewArg(ENodeList *list) { - switch (list->node->type) { - case EINDIRECT: - if (!ENODE_IS(list->node->data.monadic, EOBJREF)) - break; - if (list->node->data.monadic->data.objref->datatype != DLOCAL && !is_const_object(list->node->data.monadic->data.objref)) - break; - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EARGOBJ: - case ELOCOBJ: - case EOBJLIST: - case EVECTOR128CONST: - return CInline_CopyExpression(list->node, CopyMode0); - } - - switch (list->node->rtype->type) { - default: - CError_FATAL(4726); - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPESTRUCT: - case TYPECLASS: - case TYPEMEMBERPOINTER: - case TYPEPOINTER: - case TYPEOBJCID: - return CExpr_GetETEMPCopy(list->node); - } -} - -static ENode *CExpr_PlacementDeleteCall(Type *type, ENode *expr, Object *obj, Boolean flag1, Boolean flag2) { - ENodeList *list; - Object *funcobj; - ENode *result; - ENodeList *inputarg; - Boolean outflag; - - CError_ASSERT(4752, ENODE_IS(expr, EFUNCCALL) && ENODE_IS(expr->data.funccall.funcref, EOBJREF)); - - funcobj = expr->data.funccall.funcref->data.objref; - CError_ASSERT(4756, IS_TYPE_FUNC(funcobj->type) && TYPE_FUNC(funcobj->type)->args && TYPE_FUNC(funcobj->type)->args->next); - - funcobj = CParser_FindDeallocationObject(type, TYPE_FUNC(funcobj->type)->args->next, flag1, flag2, &outflag); - if (!funcobj) - return NULL; - - result = CExpr_NewENode(EFUNCCALL); - result->type = EFUNCCALL; - result->cost = 4; - result->rtype = &stvoid; - result->data.funccall.funcref = create_objectrefnode(funcobj); - result->data.funccall.functype = TYPE_FUNC(funcobj->type); - funcobj->flags |= OBJECT_USED; - - list = lalloc(sizeof(ENodeList)); - list->node = create_objectnode(obj); - result->data.funccall.args = list; - - CError_ASSERT(4780, (inputarg = expr->data.funccall.args) && (inputarg = inputarg->next)); - - do { - list->next = lalloc(sizeof(ENodeList)); - list = list->next; - list->node = CExpr_CopyPlacementNewArg(inputarg); - inputarg = inputarg->next; - } while (inputarg); - list->next = NULL; - - return result; -} - -static Type *scan_type_name(UInt32 *qual) { - DeclInfo di; - memclrw(&di, sizeof(DeclInfo)); - - CParser_GetDeclSpecs(&di, 0); - di.x46 = 1; - scandeclarator(&di); - - if (di.name) - CError_Error(CErrorStr146); - - firstarrayexpr = di.x24; - *qual = di.qual; - return di.thetype; -} - -static UInt32 cv_qualifier_list(void) { - UInt32 qual; - - qual = 0; - tk = lex(); - while (tk >= TK_CONST && tk <= TK_ASM) { - switch (tk) { - case TK_CONST: - if (qual & Q_CONST) - CError_Error(CErrorStr121); - qual |= Q_CONST; - break; - case TK_VOLATILE: - if (qual & Q_VOLATILE) - CError_Error(CErrorStr121); - qual |= Q_VOLATILE; - break; - default: - CError_Error(CErrorStr121); - } - - tk = lex(); - } - - return qual; -} - -static void scan_new_declarator(DeclInfo *di, Boolean flag) { - NameResult pr; - SInt32 size; - ENode *expr; - - switch (tk) { - case '*': - makethetypepointer(di, cv_qualifier_list()); - if (tk != '[') - scan_new_declarator(di, flag); - break; - case TK_IDENTIFIER: - case TK_COLON_COLON: - if (CScope_ParseQualifiedNameSpace(&pr, 1, 0) && pr.nspace_0 && pr.nspace_0->theclass && tk == '*') { - makememberpointertype(di, pr.nspace_0->theclass, cv_qualifier_list()); - if (tk != '[') - scan_new_declarator(di, flag); - } else { - CError_Error(CErrorStr121); - } - break; - } - - if (tk == '[') { - tk = lex(); - expr = expression(); - - if (IS_TYPE_ENUM(expr->rtype)) - expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; - if (!IS_TYPE_INT(expr->rtype)) - CError_Error(CErrorStr146); - - if (tk != ']') - CError_Error(CErrorStr125); - else - tk = lex(); - - if (tk == '[') - scan_new_declarator(di, 0); - - if (CanCreateObject(di->thetype) && IsCompleteType(di->thetype)) { - di->thetype = CDecl_NewArrayType(di->thetype, 0); - if (!ENODE_IS(expr, EINTCONST)) { - size = 1; - if (!flag) - CError_Error(CErrorStr124); - else - firstarrayexpr = expr; - } else { - size = CInt64_GetULong(&expr->data.intval); - } - TYPE_POINTER(di->thetype)->size = size * TYPE_POINTER(di->thetype)->target->size; - } else { - CError_Error(CErrorStr129); - } - } -} - -static Type *scan_new_type_name(UInt32 *qual) { - DeclInfo di; - memclrw(&di, sizeof(DeclInfo)); - - di.x4F = 1; - CParser_GetDeclSpecs(&di, 0); - scan_new_declarator(&di, 1); - - *qual = di.qual; - return di.thetype; -} - -static ENode *CExpr_NewAlloc(Type *type, ENodeList *args, Boolean flag1, Boolean flag2) { - NameSpaceObjectList *list; - Object *obj; - Boolean found; - HashNameNode *name; - NameResult pr; - - found = 0; - if (!flag1 && IS_TYPE_CLASS(type)) { - list = NULL; - obj = NULL; - name = (flag2 && copts.array_new_delete) ? newa_fobj->name : newp_fobj->name; - if (CScope_FindClassMemberObject(TYPE_CLASS(type), &pr, name)) { - list = pr.nsol_14; - obj = OBJECT(pr.obj_10); - CError_ASSERT(4935, list || obj); - found = 1; - } else if (TYPE_CLASS(type)->flags & CLASS_HANDLEOBJECT) { - CError_ASSERT(4942, !flag2); - obj = newh_func; - found = 1; - } - } - - if (!found) { - if (flag2 && copts.array_new_delete) - list = &newa_fobj->first; - else - list = &newp_fobj->first; - obj = NULL; - } - - return CExpr_GenericFuncCall(NULL, NULL, 0, obj, list, NULL, args, 0, 0, 1); -} - -static ENode *CExpr_NewExceptionSafeAlloc(Type *type, ENode *node, ENodeList *args, Boolean flag1, Boolean flag2, Object **objptr) { - Object *obj; - ENode *result; - ENode *catchexpr; - Object *deletefunc; - Boolean include_size; - - if (!cscope_currentfunc || !copts.delete_exception || !copts.exceptions) - return NULL; - - obj = create_temp_object(TYPE(&void_ptr)); - *objptr = obj; - deletefunc = NULL; - catchexpr = NULL; - include_size = 0; - if (args) - catchexpr = CExpr_PlacementDeleteCall(type, node, obj, flag1, flag2); - if (!args) - deletefunc = CParser_FindDeallocationObject(type, NULL, flag1, flag2, &include_size); - - if (!deletefunc && !catchexpr) - return NULL; - - result = lalloc(sizeof(ENode)); - *result = *node; - node = makediadicnode(create_objectnode(obj), node, EASS); - if (!catchexpr && !include_size) { - result->type = ENEWEXCEPTION; - result->data.newexception.initexpr = node; - result->data.newexception.tryexpr = NULL; - result->data.newexception.pointertemp = obj; - result->data.newexception.deletefunc = deletefunc; - } else { - if (!catchexpr) - catchexpr = CExpr_DeleteFuncCall(deletefunc, create_objectnode(obj), type, include_size); - result->type = EINITTRYCATCH; - result->data.itc.initexpr = node; - result->data.itc.tryexpr = NULL; - result->data.itc.result = create_objectnode(obj); - result->data.itc.catchexpr = catchexpr; - } - - return result; -} - -static ENode *CExpr_NewExceptionSafeInit(ENode *expr, ENode *tryexpr) { - switch (expr->type) { - case ENEWEXCEPTION: - expr->data.newexception.tryexpr = tryexpr; - break; - case EINITTRYCATCH: - expr->data.itc.tryexpr = tryexpr; - break; - default: - CError_FATAL(5056); - } - return expr; -} - -static ENode *CExpr_NewArray(Type *type, UInt32 qual, ENodeList *nodelist, Boolean flag) { - Type *tptr; - Type *sizetype; - Type *innertype; - ENodeList *newlist; - ENode *result; - Object *ctor; - Object *dtor; - ENode *ass; - ENode *etemp; - ENode *mul; - SInt32 count; - ENode *newalloc; - ENode *newESalloc; - Object *tempobj; - ENode *callexpr; - - tptr = CDecl_NewPointerType(TYPE_POINTER(type)->target); - sizetype = CABI_GetSizeTType(); - innertype = TYPE_POINTER(type)->target; - while (IS_TYPE_ARRAY(innertype)) - innertype = TYPE_POINTER(innertype)->target; - - if (!CanAllocObject(innertype) || !IsCompleteType(innertype)) - return nullnode(); - - newlist = lalloc(sizeof(ENodeList)); - newlist->next = nodelist; - if (tk == '(') { - tk = lex(); - if (CExpr_ScanExpressionList(1)) - CError_Error(CErrorStr174); - if (tk == ')') - tk = lex(); - else - CError_Error(CErrorStr115); - } - - if (!IS_TYPE_CLASS(innertype) || CClass_IsPODClass(TYPE_CLASS(innertype))) { - newlist->node = intconstnode(sizetype, type->size); - if (firstarrayexpr) { - newlist->node = makediadicnode(newlist->node, promote(firstarrayexpr, sizetype), EMUL); - optimizecomm(newlist->node); - } - result = CExpr_NewAlloc(innertype, newlist, flag, 1); - result->rtype = tptr; - result->flags |= (qual & ENODE_FLAG_QUALS); - return result; - } - - ctor = NULL; - if (CClass_Constructor(TYPE_CLASS(innertype))) { - ctor = CClass_DefaultConstructor(TYPE_CLASS(innertype)); - if (ctor) { - ctor->flags |= OBJECT_USED; - } else { - ctor = CClass_DummyDefaultConstructor(TYPE_CLASS(innertype)); - if (!ctor) - CError_Error(CErrorStr203); - } - } - - dtor = CClass_Destructor(TYPE_CLASS(innertype)); - if (dtor) - dtor = CABI_GetDestructorObject(dtor, CABIDestroy1); - - ass = NULL; - if (firstarrayexpr) { - etemp = CExpr_NewETEMPNode(sizetype, 1); - mul = promote(firstarrayexpr, sizetype); - if (innertype->size) - count = type->size / innertype->size; - else - count = 0; - if (count > 1) { - mul = makediadicnode(mul, intconstnode(sizetype, count), EMUL); - optimizecomm(mul); - } - ass = makediadicnode(CExpr_DerefETEMPCopy(etemp), mul, EASS); - mul = makediadicnode(CExpr_DerefETEMPCopy(etemp), intconstnode(sizetype, innertype->size), EMUL); - optimizecomm(mul); - mul = makediadicnode(mul, intconstnode(sizetype, 16), EADD); - optimizecomm(mul); - newlist->node = mul; - etemp = CExpr_DerefETEMPCopy(etemp); - } else { - newlist->node = intconstnode(sizetype, type->size + 16); - if (innertype->size) - count = type->size / innertype->size; - else - count = 0; - etemp = intconstnode(sizetype, count); - } - - newalloc = CExpr_NewAlloc(innertype, newlist, flag, 1); - newalloc->rtype = tptr; - newESalloc = CExpr_NewExceptionSafeAlloc(innertype, newalloc, nodelist, 1, flag, &tempobj); - if (newESalloc) { - callexpr = CExpr_FuncCallSix( - cnar_func, - create_objectnode(tempobj), - ctor ? create_objectrefnode(ctor) : nullnode(), - dtor ? create_objectrefnode(dtor) : nullnode(), - intconstnode(sizetype, innertype->size), - etemp, - NULL - ); - result = CExpr_NewExceptionSafeInit(newESalloc, makediadicnode(create_objectnode(tempobj), callexpr, EASS)); - } else { - result = CExpr_FuncCallSix( - cnar_func, - newalloc, - ctor ? create_objectrefnode(ctor) : nullnode(), - dtor ? create_objectrefnode(dtor) : nullnode(), - intconstnode(sizetype, innertype->size), - etemp, - NULL - ); - } - - if (ass) - result = makecommaexpression(ass, result); - result->rtype = tptr; - result->flags |= (qual & ENODE_FLAG_QUALS); - return result; -} - -static ENode *CExpr_NewSimpleClass(TypeClass *tclass, ENode *expr, ENodeList *args) { - ENode *precomp; - ENode *nullcheck; - - precomp = lalloc(sizeof(ENode)); - *precomp = *expr; - precomp->type = EPRECOMP; - precomp->data.precompid = CParser_GetUniqueID(); - - nullcheck = lalloc(sizeof(ENode)); - *nullcheck = *expr; - nullcheck->type = ENULLCHECK; - nullcheck->cost = 4; - nullcheck->data.nullcheck.nullcheckexpr = expr; - nullcheck->data.nullcheck.condexpr = CExpr_ConstructObject(tclass, precomp, args, 0, 1, 1, 1, 1); - nullcheck->data.nullcheck.precompid = precomp->data.precompid; - return nullcheck; -} - -static ENode *CExpr_NewClass(TypeClass *tclass, ENode *expr, ENodeList *args1, ENodeList *args2, Boolean flag) { - Object *objptr; - ENode *newESalloc; - - if (!args2 && !flag && CABI_ConstructorCallsNew(tclass)) { - expr = nullnode(); - expr->rtype = CDecl_NewPointerType(TYPE(tclass)); - return CExpr_ConstructObject(tclass, expr, args1, 0, 1, 1, 1, 1); - } else { - newESalloc = CExpr_NewExceptionSafeAlloc(TYPE(tclass), expr, args2, 0, flag, &objptr); - if (newESalloc) { - return CExpr_NewExceptionSafeInit( - newESalloc, - CExpr_ConstructObject(tclass, create_objectnode(objptr), args1, 0, 1, 1, 1, 1)); - } else { - return CExpr_NewSimpleClass(tclass, expr, args1); - } - } -} - -ENode *scannew(Boolean flag) { - Type *type; // r27 - UInt32 qual; - ENodeList *args; // r28 - Boolean placement_flag; // r26 - ENodeList *newargs; // r26 - ENode *expr; // r26 - ENodeList *args2; // r29 - Object *tempobj; - ENode *newESalloc; // r28 - ENode *tempobj_expr; // r25 - ENode *etemp_expr; // r28 - ENode *indirect_expr; // r25 - ENode *ass; // r25 - ENode *cond; // r27 - - type = NULL; - args = NULL; - firstarrayexpr = NULL; - if ((tk = lex()) == '(') { - tk = lex(); - placement_flag = isdeclaration(1, 1, 1, ')'); - if (!placement_flag) - args = CExpr_ScanExpressionList(1); - if (placement_flag) - type = scan_type_name(&qual); - if (tk != ')') - CError_Error(CErrorStr115); - else - tk = lex(); - } - - if (!type) { - if (tk == '(') { - tk = lex(); - type = scan_type_name(&qual); - if (tk != ')') - CError_Error(CErrorStr115); - else - tk = lex(); - } else { - type = scan_new_type_name(&qual); - } - } - - if (IS_TYPE_ARRAY(type)) - return CExpr_NewArray(type, qual, args, flag); - - if (IS_TYPE_CLASS(type)) { - if (TYPE_CLASS(type)->sominfo) - return CSOM_New(TYPE_CLASS(type)); - if (TYPE_CLASS(type)->objcinfo) - return CObjC_New(TYPE_CLASS(type)); - } - - if (!IsCompleteType(type) || !CanAllocObject(type)) - return nullnode(); - - newargs = lalloc(sizeof(ENodeList)); - newargs->next = args; - newargs->node = intconstnode(CABI_GetSizeTType(), type->size); - - expr = CExpr_NewAlloc(type, newargs, flag, 0); - expr->rtype = CDecl_NewPointerType(type); - expr->flags |= (qual & ENODE_FLAG_QUALS); - - if (tk == '(') { - tk = lex(); - args2 = CExpr_ScanExpressionList(1); - if (!args2 && !IS_TYPE_CLASS(type)) { - args2 = lalloc(sizeof(ENodeList)); - memclrw(args2, sizeof(ENodeList)); - args2->node = do_typecast(nullnode(), type, 0); - } - if (tk == ')') - tk = lex(); - else - CError_Error(CErrorStr115); - } else { - args2 = NULL; - } - - if (ENODE_IS(expr, EINTCONST)) - return expr; - - if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type))) - return CExpr_NewClass(TYPE_CLASS(type), expr, args2, args, flag); - - if (args2) { - if (args2->next) { - CError_Error(CErrorStr174); - return nullnode(); - } - - newESalloc = CExpr_NewExceptionSafeAlloc(type, expr, args, 0, flag, &tempobj); - if (newESalloc) { - tempobj_expr = makemonadicnode(create_objectnode(tempobj), EINDIRECT); - tempobj_expr->rtype = type; - tempobj_expr->flags = args2->node->flags & ENODE_FLAG_QUALS; - return CExpr_NewExceptionSafeInit( - newESalloc, - makediadicnode(tempobj_expr, CExpr_AssignmentPromotion(args2->node, type, newESalloc->flags, 1), EASS) - ); - } else { - etemp_expr = CExpr_GetETEMPCopy(expr); - indirect_expr = makemonadicnode(etemp_expr, EINDIRECT); - indirect_expr->rtype = type; - indirect_expr->flags = args2->node->flags & ENODE_FLAG_QUALS; - ass = makediadicnode(indirect_expr, CExpr_AssignmentPromotion(args2->node, type, indirect_expr->flags, 1), EASS); - cond = CExpr_NewENode(ECOND); - cond->cost = 4; - cond->rtype = &stvoid; - cond->data.cond.cond = expr; - cond->data.cond.expr1 = ass; - cond->data.cond.expr2 = nullnode(); - cond = makecommaexpression(cond, etemp_expr); - cond->rtype = etemp_expr->rtype; - cond->flags = etemp_expr->flags; - return cond; - } - } else { - return expr; - } -} - -static ENode *CExpr_DeleteArray(ENode *expr, Type *type, Boolean flag) { - Object *obj; - Object *dtor; - Boolean outflag; - ENode *precomp; - SInt32 precompid; - ENode *tmp; - ENode *result; - - obj = CParser_FindDeallocationObject(type, NULL, 1, flag, &outflag); - - if (!IS_TYPE_CLASS(type) || CClass_IsPODClass(TYPE_CLASS(type))) - return CExpr_DeleteFuncCall(obj, expr, type, outflag); - - dtor = CClass_Destructor(TYPE_CLASS(type)); - if (dtor || outflag) { - if (obj->nspace == cscope_root && !outflag) { - return funccallexpr(dnar_func, expr, dtor ? create_objectrefnode(dtor) : nullnode(), NULL, NULL); - } - return funccallexpr( - dnar3_func, - expr, - dtor ? create_objectrefnode(dtor) : nullnode(), - create_objectrefnode(obj), - intconstnode(TYPE(&stsignedshort), outflag)); - } - - precomp = lalloc(sizeof(ENode)); - *precomp = *expr; - precomp->type = EPRECOMP; - precomp->data.precompid = precompid = CParser_GetUniqueID(); - tmp = CExpr_DeleteFuncCall(obj, makediadicnode(precomp, intconstnode(CABI_GetSizeTType(), 16), ESUB), type, 0); - - result = CExpr_NewENode(ENULLCHECK); - result->rtype = &stvoid; - result->cost = 4; - result->data.nullcheck.nullcheckexpr = expr; - result->data.nullcheck.condexpr = tmp; - result->data.nullcheck.precompid = precompid; - - return result; -} - -ENode *scandelete(Boolean flag) { - Boolean is_array; // r24 - ENode *expr; // r25 - Type *conv_type; // r22 - UInt32 conv_qual; // r23 - Type *innertype; // r23 - Type *t; - Object *obj; - Object *dtor; // r24 - ENode *result_expr; // r24??? - ENode *precomp_orig; // r31 - SInt32 precompid; // r30 - Boolean is_virtual; // r23 - ENode *nc; - ConversionIterator iter; - Boolean outflag; - BClassList path; - - if ((tk = lex()) == '[') { - if ((tk = lex()) != ']') - CError_Error(CErrorStr125); - else - tk = lex(); - is_array = 1; - } else { - is_array = 0; - } - - expr = cast_expression(); - if (!IS_TYPE_POINTER_ONLY(expr->rtype)) { - if (IS_TYPE_CLASS(expr->rtype)) { - conv_type = NULL; - CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype)); - while ((obj = CExpr_ConversionIteratorNext(&iter))) { - if (IS_TYPE_POINTER_ONLY(TYPE_FUNC(obj->type)->functype)) { - if (conv_type) { - CError_Error(CErrorStr199); - break; - } - conv_type = TYPE_FUNC(obj->type)->functype; - conv_qual = TYPE_FUNC(obj->type)->qual; - } - } - if (conv_type) { - if (!copts.old_argmatch) { - expr = CExpr_Convert(expr, conv_type, conv_qual, 1, 1); - } else { - if (user_assign_check(expr, conv_type, conv_qual, 1, 0, 1)) - expr = assign_node; - } - } - } - if (!IS_TYPE_POINTER_ONLY(expr->rtype)) { - CError_Error(CErrorStr146); - return nullnode(); - } - } - - innertype = TYPE_POINTER(expr->rtype)->target; - if (innertype->size == 0) - CDecl_CompleteType(innertype); - - if (IS_TYPE_ARRAY(innertype) && !is_array) - CError_Error(CErrorStr146); - - if (is_array) { - t = innertype; - while (IS_TYPE_ARRAY(t)) - t = TYPE_POINTER(t)->target; - return CExpr_DeleteArray(expr, t, flag); - } - - if (copts.objective_c && CObjC_IsType_id(expr->rtype)) - return CObjC_Delete(NULL, expr); - - if (!IS_TYPE_CLASS(innertype)) { - obj = CParser_FindDeallocationObject(innertype, NULL, 0, flag, &outflag); - CClass_CheckObjectAccess(NULL, obj); - return CExpr_DeleteFuncCall(obj, expr, innertype, outflag); - } - - if (TYPE_CLASS(innertype)->sominfo) - return CSOM_Delete(TYPE_CLASS(innertype), expr); - - if (TYPE_CLASS(innertype)->objcinfo) - return CObjC_Delete(TYPE_CLASS(innertype), expr); - - if (!(TYPE_CLASS(innertype)->flags & CLASS_COMPLETED) && copts.pedantic) - CError_Warning(CErrorStr136, innertype, 0); - - obj = CParser_FindDeallocationObject(innertype, NULL, 0, flag, &outflag); - CClass_CheckObjectAccess(NULL, obj); - dtor = CClass_Destructor(TYPE_CLASS(innertype)); - if (!dtor) - return CExpr_DeleteFuncCall(obj, expr, innertype, outflag); - - path.next = NULL; - path.type = innertype; - CClass_CheckObjectAccess(&path, dtor); - - result_expr = lalloc(sizeof(ENode)); - result_expr->type = EFUNCCALL; - result_expr->cost = 4; - result_expr->flags = 0; - result_expr->rtype = &stvoid; - if (dtor->datatype == DVFUNC) { - precomp_orig = expr; - expr = lalloc(sizeof(ENode)); - *expr = *precomp_orig; - expr->type = EPRECOMP; - expr->data.precompid = precompid = CParser_GetUniqueID(); - is_virtual = 1; - } else { - is_virtual = 0; - } - - if (!flag) { - result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 1); - } else { - CError_ASSERT(5650, !outflag); - result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 0); - result_expr->rtype = TYPE(&void_ptr); - result_expr = funccallexpr(obj, result_expr, NULL, NULL, NULL); - obj->flags |= OBJECT_USED; - } - - if (is_virtual) { - nc = lalloc(sizeof(ENode)); - nc->type = ENULLCHECK; - nc->rtype = &stvoid; - nc->cost = 4; - nc->flags = 0; - nc->data.nullcheck.nullcheckexpr = precomp_orig; - nc->data.nullcheck.condexpr = result_expr; - nc->data.nullcheck.precompid = precompid; - return nc; - } else { - return result_expr; - } -} |