summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CExpr.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CExpr.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/CExpr.c')
-rw-r--r--compiler_and_linker/unsorted/CExpr.c4971
1 files changed, 0 insertions, 4971 deletions
diff --git a/compiler_and_linker/unsorted/CExpr.c b/compiler_and_linker/unsorted/CExpr.c
deleted file mode 100644
index 484f56d..0000000
--- a/compiler_and_linker/unsorted/CExpr.c
+++ /dev/null
@@ -1,4971 +0,0 @@
-#include "compiler/CExpr.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CIRTransform.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CInt64.h"
-#include "compiler/CObjC.h"
-#include "compiler/CObjCModern.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CRTTI.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PPCError.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-Boolean (*name_obj_check)(HashNameNode *, Object *);
-Boolean disallowgreaterthan;
-
-// forward declarations
-static ENode *makeaddnode(ENode *left, ENode *right);
-static ENode *makesubnode(ENode *left, ENode *right);
-
-ENode *CExpr_RewriteConst(ENode *expr) {
- Object *obj;
-
-restart:
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EOBJREF)) {
- obj = expr->data.monadic->data.objref;
- if (obj->datatype == DALIAS) {
- CExpr_AliasTransform(expr->data.monadic);
- goto restart;
- }
-
- if ((obj->qual & Q_INLINE_DATA) && expr->rtype == obj->type) {
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- expr->type = EINTCONST;
- expr->data.intval = obj->u.data.u.intconst;
- break;
- case TYPEPOINTER:
- expr->type = EINTCONST;
- expr->data.intval = obj->u.data.u.intconst;
- expr->rtype = TYPE(&stunsignedlong);
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = obj->type;
- break;
- case TYPEFLOAT:
- expr->type = EFLOATCONST;
- if (obj->u.data.u.floatconst)
- expr->data.floatval = *obj->u.data.u.floatconst;
- else
- expr->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), cint64_zero);
- break;
- default:
- CError_FATAL(105);
- }
- }
- }
-
- return expr;
-}
-
-void optimizecomm(ENode *expr) {
- ENode *right;
- ENode *left;
-
- if (ENODE_IS((right = expr->data.diadic.right), EINTCONST))
- return;
- if (ENODE_IS((left = expr->data.diadic.left), EINTCONST)) {
- swap:
- expr->data.diadic.right = left;
- expr->data.diadic.left = right;
- return;
- }
-
- if (ENODE_IS(left, EFLOATCONST))
- return;
- if (ENODE_IS(right, EFLOATCONST))
- goto swap;
-
- if (expr->rtype->type > TYPEFLOAT)
- return;
-
- if (left->cost > right->cost)
- goto swap;
-}
-
-static void checkadditive(ENode *expr) {
- switch (expr->rtype->type) {
- case TYPEINT:
- if (expr->rtype == TYPE(&stbool))
- break;
- case TYPEFLOAT:
- return;
- case TYPEENUM:
- if (copts.cplusplus)
- break;
- return;
- case TYPEPOINTER:
- if (TPTR_TARGET(expr->rtype)->size == 0)
- CDecl_CompleteType(TPTR_TARGET(expr->rtype));
- if (TPTR_TARGET(expr->rtype)->size == 0)
- break;
- return;
- case TYPEARRAY:
- if (ENODE_IS(expr, EOBJREF))
- return;
- }
-
- CError_Error(CErrorStr376, expr->rtype, ENODE_QUALS(expr));
-}
-
-static void CExpr_CompareConvert(ENode **leftp, char *opname, ENode **rightp, Boolean flag) {
- ENode *left;
- ENode *right;
- CInt64 val;
-
- left = *leftp;
- right = *rightp;
-
- switch (left->rtype->type) {
- case TYPEINT:
- break;
- case TYPEFLOAT:
- if (left->rtype != right->rtype)
- CExpr_ArithmeticConversion(leftp, rightp);
- return;
- case TYPEENUM:
- left->rtype = TYPE_ENUM(left->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr377,
- left->rtype, ENODE_QUALS(left),
- opname,
- right->rtype, ENODE_QUALS(right));
- left = nullnode();
- }
-
- switch (right->rtype->type) {
- case TYPEINT:
- break;
- case TYPEFLOAT:
- CExpr_ArithmeticConversion(leftp, rightp);
- return;
- case TYPEENUM:
- right->rtype = TYPE_ENUM(right->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr377,
- left->rtype, ENODE_QUALS(left),
- opname,
- right->rtype, ENODE_QUALS(right));
- right = nullnode();
- }
-
- if (left->rtype == right->rtype) {
- *leftp = left;
- *rightp = right;
- return;
- }
-
- if (left->rtype->size == right->rtype->size) {
- if (is_unsigned(left->rtype) == is_unsigned(right->rtype)) {
- left->rtype = right->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- } else {
- if (ENODE_IS(right, EINTCONST) && left->rtype->size <= right->rtype->size && (is_unsigned(left->rtype) == is_unsigned(right->rtype) || is_unsigned(left->rtype))) {
- val = CMach_CalcIntDiadic(left->rtype, right->data.intval, '+', cint64_zero);
- val = CMach_CalcIntDiadic(right->rtype, val, '+', cint64_zero);
- if (CInt64_Equal(val, right->data.intval)) {
- right->rtype = left->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- }
-
- if (ENODE_IS(left, EINTCONST) && left->rtype->size >= right->rtype->size && (is_unsigned(left->rtype) == is_unsigned(right->rtype) || is_unsigned(right->rtype))) {
- val = CMach_CalcIntDiadic(right->rtype, left->data.intval, '+', cint64_zero);
- val = CMach_CalcIntDiadic(left->rtype, val, '+', cint64_zero);
- if (CInt64_Equal(val, left->data.intval)) {
- left->rtype = right->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- }
- }
-
- *leftp = left;
- *rightp = right;
- CExpr_ArithmeticConversion(leftp, rightp);
-}
-
-static ENode *CExpr_ConstResult(ENode *expr, SInt32 value) {
- ENode *constnode;
-
- if (IS_TYPE_FLOAT(expr->rtype)) {
- constnode = intconstnode(TYPE(&stsignedint), value);
- constnode->type = EFLOATCONST;
- constnode->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedint), constnode->data.intval);
- constnode->rtype = expr->rtype;
- } else {
- constnode = intconstnode(expr->rtype, value);
- }
-
- if (CInline_ExpressionHasSideEffect(expr))
- return makediadicnode(expr, constnode, ECOMMA);
- else
- return constnode;
-}
-
-static ENode *makemultnode(ENode *left, ENode *right) {
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(left))
- return CExpr_ConstResult(right, 0);
- if (iszero(right))
- return CExpr_ConstResult(left, 0);
-
- if (CExpr_IsOne(right))
- return left;
- if (CExpr_IsOne(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '*', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '*', right->data.floatval);
- return left;
- }
-
- left = makediadicnode(left, right, EMUL);
- optimizecomm(left);
- if (IS_TYPE_INT(left->rtype) && left->rtype->size > 2) {
- left->cost++;
- if (left->cost > 200)
- left->cost = 200;
- }
-
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
-
- return left;
-}
-
-static ENode *makedivnode(ENode *left, ENode *right, Boolean no_warning) {
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right) && IS_TYPE_INT(right->rtype)) {
- if (!no_warning)
- CError_Warning(CErrorStr139);
- return right;
- }
-
- if (CExpr_IsOne(right))
- return left;
-
- if (iszero(left) && IS_TYPE_INT(left->rtype))
- return CExpr_ConstResult(right, 0);
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '/', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '/', right->data.floatval);
- return left;
- }
-
- left = makediadicnode(left, right, EDIV);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
-
- return left;
-}
-
-static short canadd2(ENode *expr, CInt64 value) {
- Float tmp;
-
- if (CInt64_IsZero(&value))
- return 1;
-
- switch (expr->type) {
- case EINTCONST:
- expr->data.intval = CMach_CalcIntDiadic(expr->rtype, expr->data.intval, '+', value);
- return 1;
- case EFLOATCONST:
- tmp = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), value);
- expr->data.floatval = CMach_CalcFloatDiadic(expr->rtype, expr->data.floatval, '+', tmp);
- return 1;
- case EADD:
- if (canadd2(expr->data.diadic.left, value))
- return 1;
- if (canadd2(expr->data.diadic.right, value))
- return 1;
- return 0;
- case ESUB:
- if (canadd2(expr->data.diadic.left, value))
- return 1;
- if (canadd2(expr->data.diadic.right, CInt64_Neg(value)))
- return 1;
- return 0;
- case ETYPCON:
- if (IS_TYPE_POINTER_ONLY(expr->rtype) && ENODE_IS(expr->data.monadic, EINTCONST)) {
- expr->data.monadic->data.intval = CMach_CalcIntDiadic(TYPE(&stunsignedlong), expr->data.monadic->data.intval, '+', value);
- return 1;
- }
- return 0;
- default:
- return 0;
- }
-}
-
-short canadd(ENode *expr, SInt32 value) {
- CInt64 value64;
- CInt64_SetLong(&value64, value);
- return canadd2(expr, value64);
-}
-
-static ENode *addconst(ENode *expr, SInt32 value) {
- ENode *right;
-
- if (canadd(expr, value))
- return expr;
-
- if (stsignedint.size < 4 && (value > 0x7FFF || value < -0x8000))
- right = intconstnode(TYPE(&stsignedlong), value);
- else
- right = intconstnode(TYPE(&stsignedint), value);
-
- CExpr_ArithmeticConversion(&expr, &right);
- expr = makediadicnode(expr, right, EADD);
- return expr;
-}
-
-static ENode *integralpointerpromote(ENode *expr) {
- Boolean uns;
- Type *type;
-
- if (!IS_TYPE_INT(expr->rtype))
- expr = forceintegral(expr);
-
- if (expr->rtype->size != 4) {
- type = TYPE(&stunsignedlong);
- if (is_unsigned(type) != (uns = is_unsigned(expr->rtype))) {
- if (uns) {
- if (stunsignedlong.size == 4) {
- type = TYPE(&stunsignedlong);
- } else if (stunsignedint.size == 4) {
- type = TYPE(&stunsignedint);
- } else {
- CError_FATAL(480);
- }
- } else {
- if (stsignedlong.size == 4) {
- type = TYPE(&stsignedlong);
- } else if (stsignedint.size == 4) {
- type = TYPE(&stsignedint);
- } else {
- CError_FATAL(486);
- }
- }
- }
-
- if (ENODE_IS(expr, EINTCONST))
- expr->data.intval = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval);
- else
- expr = makemonadicnode(expr, ETYPCON);
-
- expr->rtype = type;
- }
-
- return expr;
-}
-
-static ENode *padd(ENode *left, ENode *right) {
- Type *innertype;
- SInt32 innersize;
- ENode *expr;
-
- right = integralpointerpromote(right);
- innertype = TPTR_TARGET(left->rtype);
- innersize = innertype->size;
- if (innersize == 0) {
- CDecl_CompleteType(innertype);
- innersize = innertype->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- expr = makemultnode(
- right,
- intconstnode((innersize > 0x7FFF) ? TYPE(&stsignedlong) : TYPE(&stsignedint), innersize));
-
- if (ENODE_IS(expr, EINTCONST) && canadd2(left, expr->data.intval))
- return left;
-
- if (ENODE_IS(left, EADD) && ENODE_IS(left->data.diadic.right, EINTCONST)) {
- left->data.diadic.left = makediadicnode(left->data.diadic.left, expr, EADD);
- return left;
- }
-
- expr = makediadicnode(left, expr, EADD);
- expr->rtype = left->rtype;
- expr->flags = left->flags;
- return expr;
-}
-
-static ENode *psub(ENode *left, ENode *right) {
- Type *innertype;
- SInt32 innersize;
- ENode *expr;
-
- if (IS_TYPE_POINTER(right->rtype)) {
- innersize = TPTR_TARGET(left->rtype)->size;
- if (innersize == 0) {
- CDecl_CompleteType(TPTR_TARGET(left->rtype));
- innersize = TPTR_TARGET(left->rtype)->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- if (!is_typeequal(left->rtype, right->rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- return left;
- }
-
- if (ENODE_IS(left, ETYPCON) && ENODE_IS(left->data.monadic, EINTCONST) && ENODE_IS(right, ETYPCON) && ENODE_IS(right->data.monadic, EINTCONST)) {
- left->data.monadic->rtype = right->data.monadic->rtype = CABI_GetPtrDiffTType();
- expr = makesubnode(left->data.monadic, right->data.monadic);
- if (innersize > 1)
- expr = makedivnode(expr, intconstnode(CABI_GetPtrDiffTType(), innersize), 11);
- return expr;
- }
-
- expr = makediadicnode(left, right, ESUB);
- expr->rtype = CABI_GetPtrDiffTType();
- if (innersize > 1)
- expr = makediadicnode(expr, intconstnode(CABI_GetPtrDiffTType(), innersize), EDIV);
- return expr;
- }
-
- right = integralpointerpromote(right);
- innertype = TPTR_TARGET(left->rtype);
- innersize = innertype->size;
- if (innersize == 0) {
- CDecl_CompleteType(innertype);
- innersize = innertype->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- expr = makemultnode(right, intconstnode(CABI_GetPtrDiffTType(), innersize));
- if (ENODE_IS(expr, EINTCONST) && canadd2(left, CInt64_Neg(expr->data.intval)))
- return left;
-
- expr = makediadicnode(left, expr, ESUB);
- expr->rtype = left->rtype;
- expr->flags = left->flags;
- return expr;
-}
-
-static ENode *makeaddnode(ENode *left, ENode *right) {
- if (IS_TYPE_POINTER(left->rtype))
- return padd(left, right);
- if (IS_TYPE_POINTER(right->rtype))
- return padd(right, left);
-
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right))
- return left;
- if (iszero(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '+', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '+', right->data.floatval);
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && canadd2(right, left->data.intval))
- return right;
- if (ENODE_IS(right, EINTCONST) && canadd2(left, right->data.intval))
- return left;
-
- left = makediadicnode(left, right, EADD);
- optimizecomm(left);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
- return left;
-}
-
-static ENode *makesubnode(ENode *left, ENode *right) {
- if (ENODE_IS(right, EINTCONST) && !is_unsigned(right->rtype) && !IS_TYPE_FLOAT(left->rtype)) {
- right->data.intval = CInt64_Neg(right->data.intval);
- return makeaddnode(left, right);
- }
-
- if (IS_TYPE_POINTER(left->rtype))
- return psub(left, right);
-
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right))
- return left;
- if (iszero(left)) {
- if (ENODE_IS(right, EINTCONST)) {
- right->data.intval = CInt64_Neg(right->data.intval);
- return right;
- }
- if (ENODE_IS(right, EFLOATCONST)) {
- right->data.floatval = CMach_CalcFloatMonadic(right->rtype, '-', right->data.floatval);
- return right;
- }
- return CExpr_UnaryFloatExpression(makemonadicnode(right, EMONMIN));
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '-', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '-', right->data.floatval);
- return left;
- }
-
- if (ENODE_IS(right, EINTCONST) && canadd2(left, CInt64_Neg(right->data.intval)))
- return left;
-
- left = makediadicnode(left, right, ESUB);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
- return left;
-}
-
-ENode *checkreference(ENode *expr) {
- if (!IS_TYPE_REFERENCE(expr->rtype))
- return expr;
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- return expr;
-}
-
-static ENode *pointer_generation2(ENode *expr) {
- switch (expr->type) {
- case EINDIRECT:
- switch (expr->rtype->type) {
- case TYPEARRAY:
- switch (expr->data.monadic->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- expr->type = ETYPCON;
- expr->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- return expr;
- default:
- expr->data.monadic->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- expr->data.monadic->flags = expr->flags;
- return expr->data.monadic;
- }
- case TYPEFUNC:
- expr = expr->data.monadic;
- if (ENODE_IS(expr, EOBJREF) && expr->data.objref->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- return expr;
- }
- }
- return expr;
-}
-
-ENode *pointer_generation(ENode *expr) {
- return CExpr_RewriteConst(pointer_generation2(expr));
-}
-
-ENode *CExpr_PointerGeneration(ENode *expr) {
- switch (expr->type) {
- case EINDIRECT:
- switch (expr->rtype->type) {
- case TYPEARRAY:
- expr->data.monadic->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- return expr->data.monadic;
- case TYPEFUNC:
- return expr->data.monadic;
- }
- }
- return expr;
-}
-
-static void CExpr_ConstPointerCheck(ENode *expr, Type *type, short qual) {
- Type *exprtype;
- Type *b;
- Type *a;
- short exprqual;
-
- exprtype = expr->rtype;
- if (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_POINTER_ONLY(exprtype)) {
- exprqual = expr->flags;
-
- if (TPTR_TARGET(type) == &stvoid) {
- exprqual = CParser_GetCVTypeQualifiers(TPTR_TARGET(exprtype), exprqual);
- } else {
- a = TPTR_TARGET(type);
- b = TPTR_TARGET(exprtype);
- while (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b)) {
- if (CParser_IsMoreCVQualified(TPTR_QUAL(b), TPTR_QUAL(a))) {
- CError_Warning(CErrorStr220, expr->rtype, ENODE_QUALS(expr), type, qual);
- return;
- }
- a = TPTR_TARGET(a);
- b = TPTR_TARGET(b);
- }
- }
-
- if (CParser_IsMoreCVQualified(exprqual, qual)) {
- CError_Warning(CErrorStr220, expr->rtype, ENODE_QUALS(expr), type, (UInt32) qual);
- }
- }
-}
-
-ENode *oldassignmentpromotion(ENode *expr, Type *type, short qual, Boolean flag) {
- Boolean is_ref;
- UInt32 ref_qual;
- short orig_qual;
-
- is_ref = 0;
- if (!IS_TYPE_MEMBERPOINTER(type)) {
- if (IS_TYPE_REFERENCE(type)) {
- if (ENODE_IS(expr, ECOND))
- expr = CExpr_LValue(expr, 0, 0);
- expr = pointer_generation2(expr);
- ref_qual = CParser_GetCVTypeQualifiers(expr->rtype, expr->flags);
- is_ref = 1;
- } else {
- expr = pointer_generation(expr);
- }
- }
-
- if (ENODE_IS(expr, EMEMBER))
- expr = getpointertomemberfunc(expr, type, 1);
-
- if (!is_ref)
- CExpr_ConstPointerCheck(expr, type, qual);
- else
- CExpr_ConstPointerCheck(expr, TPTR_TARGET(type), qual);
-
- if (!(assign_check(expr, type, orig_qual = qual, 1, 0, flag)))
- return expr;
-
- if (is_ref) {
- if (temp_reference_init) {
- switch (TPTR_TARGET(type)->type) {
- case TYPEPOINTER:
- qual = TPTR_QUAL(TPTR_TARGET(type));
- }
- if (!(qual & Q_CONST))
- CError_Warning(CErrorStr228);
- } else {
- if (ref_qual && ref_qual > CParser_GetCVTypeQualifiers(TPTR_TARGET(type), orig_qual))
- CError_Warning(CErrorStr259);
- }
- }
-
- return assign_node;
-}
-
-ENode *argumentpromotion(ENode *expr, Type *type, short qual, Boolean flag) {
- ENode *tmp;
- ENodeList *list;
-
- if (IS_TYPE_CLASS(type) && CClass_ReferenceArgument(TYPE_CLASS(type))) {
- if ((tmp = CExpr_IsTempConstruction(expr, type, NULL)))
- return tmp;
-
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- list->node = expr;
- tmp = CExpr_ConstructObject(
- TYPE_CLASS(type),
- create_temp_node(type),
- list, 1, 1, 1, 1, 0);
- return getnodeaddress(tmp, 0);
- }
-
- return CExpr_AssignmentPromotion(expr, type, qual, flag);
-}
-
-ENode *classargument(ENode *expr) {
- ENodeList *list;
-
- if (CClass_CopyConstructor(TYPE_CLASS(expr->rtype))) {
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- list->node = expr;
- return CExpr_ConstructObject(
- TYPE_CLASS(expr->rtype),
- create_temp_node(expr->rtype),
- list, 1, 1, 1, 1, 0);
- }
-
- return expr;
-}
-
-ENodeList *CExpr_ScanExpressionList(Boolean is_parens) {
- ENodeList *list;
- ENodeList *current;
-
- if (is_parens && tk == ')')
- return NULL;
-
- list = current = lalloc(sizeof(ENodeList));
-
- while (1) {
- current->next = NULL;
- current->node = assignment_expression();
- if (copts.old_argmatch && !ENODE_IS(current->node, EMEMBER))
- current->node = pointer_generation(current->node);
-
- if (is_parens) {
- if (tk == ')')
- break;
- } else {
- if (tk == ']')
- break;
- }
-
- if (tk != ',') {
- CError_ErrorSkip(CErrorStr116);
- break;
- }
-
- tk = lex();
- current->next = lalloc(sizeof(ENodeList));
- current = current->next;
- }
-
- return list;
-}
-
-static ENode *skipcommaexpr(ENode *expr) {
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.right;
- return expr;
-}
-
-ENode *CExpr_DoExplicitConversion(Type *type, UInt32 qual, ENodeList *list) {
- Object *obj;
- ENode *tmp;
-
- if (!IS_TYPE_CLASS(type)) {
- if (!list)
- return do_typecast(nullnode(), type, qual);
- if (list->next)
- CError_Error(CErrorStr356);
- return do_typecast(pointer_generation(list->node), type, qual);
- }
-
- CDecl_CompleteType(type);
- if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, type, 0);
-
- CanCreateObject(type);
- if (!list && CClass_IsPODClass(TYPE_CLASS(type))) {
- obj = CParser_NewGlobalDataObject(NULL);
- obj->name = CParser_GetUniqueName();
- obj->nspace = cscope_root;
- obj->type = type;
- obj->qual = qual;
- obj->sclass = TK_STATIC;
- CInit_DeclareData(obj, NULL, NULL, type->size);
-
- tmp = makemonadicnode(create_temp_node(type), EINDIRECT);
- tmp->rtype = type;
- tmp->flags = qual & ENODE_FLAG_QUALS;
- return makediadicnode(tmp, create_objectnode(obj), EASS);
- }
-
- return CExpr_ConstructObject(TYPE_CLASS(type), create_temp_node(type), list, 1, 1, 1, 1, 1);
-}
-
-static ENode *CExpr_TemplArgDepCast(Type *type, UInt32 qual, ENodeList *args) {
- ENode *expr = CExpr_NewTemplDepENode(TDE_CAST);
- expr->data.templdep.u.cast.args = args;
- expr->data.templdep.u.cast.type = type;
- expr->data.templdep.u.cast.qual = qual;
- return expr;
-}
-
-static ENode *CExpr_ParseExplicitConversion(Type *type, UInt32 qual) {
- ENodeList *args;
- ENodeList *scan;
-
- if (IS_TEMPL_CLASS(type) && !CParser_CheckTemplateClassUsage(TEMPL_CLASS(type), 1))
- type = TYPE(&stsignedint);
-
- if (tk == '(')
- tk = lex();
- else
- CError_Error(CErrorStr114);
-
- args = CExpr_ScanExpressionList(1);
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- tk = lex();
- if (CTemplTool_IsTemplateArgumentDependentType(type))
- return CExpr_TemplArgDepCast(type, qual, args);
-
- for (scan = args; scan; scan = scan->next) {
- if (CTemplTool_IsTemplateArgumentDependentExpression(scan->node))
- return CExpr_TemplArgDepCast(type, qual, args);
- }
-
- return CExpr_DoExplicitConversion(type, qual, args);
-}
-
-static ENode *CExpr_MemberVarAccess(BClassList *path, ObjMemberVar *var, ENode *expr) {
- ENode *accessnode;
- BClassList *varpath;
-
- CError_ASSERT(1152, path);
-
- if (TYPE_CLASS(path->type)->sominfo)
- return CSOM_MemberVarAccess(path, var, expr);
-
- varpath = NULL;
- if (var->has_path)
- varpath = OBJ_MEMBER_VAR_PATH(var)->path;
- accessnode = CExpr_GetClassAccessNode(path, varpath, expr, NULL, var->access, 1);
- if (!accessnode)
- return nullnode();
-
- return CClass_AccessMember(accessnode, var->type, var->qual, var->offset);
-}
-
-static Boolean CExpr_IsTemplateFunc(Object *obj) {
- return IS_TEMPL_FUNC(obj->type);
-}
-
-static ENode *CExpr_ExplicitTemplateArgCheck(NameResult *pr) {
- NameSpaceObjectList *list;
- NameSpaceObjectList *newhead;
- NameSpaceObjectList *newlist;
- ENode *expr;
-
- if (pr->obj_10) {
- if (pr->obj_10->otype != OT_OBJECT || !CExpr_IsTemplateFunc(OBJECT(pr->obj_10)))
- return NULL;
-
- list = lalloc(sizeof(NameSpaceObjectList));
- memclrw(list, sizeof(NameSpaceObjectList));
- list->object = pr->obj_10;
- } else if (pr->nsol_14) {
- for (list = pr->nsol_14; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && CExpr_IsTemplateFunc(OBJECT(list->object))) {
- newhead = newlist = galloc(sizeof(NameSpaceObjectList));
- *newlist = *list;
- newlist->next = NULL;
- while ((list = list->next)) {
- if (list->object->otype == OT_OBJECT && CExpr_IsTemplateFunc(OBJECT(list->object))) {
- newlist->next = galloc(sizeof(NameSpaceObjectList));
- newlist = newlist->next;
- *newlist = *list;
- newlist->next = NULL;
- }
- }
- list = newhead;
- break;
- }
- }
- if (!list)
- return NULL;
- } else {
- return NULL;
- }
-
- expr = CExpr_NewENode(EOBJLIST);
- expr->rtype = OBJECT(list->object)->type;
- expr->data.objlist.list = list;
- expr->data.objlist.templargs = CTempl_ParseUncheckTemplArgs(NULL, 0);
-
- tk = lex();
- return expr;
-}
-
-ENode *CExpr_MakeNameLookupResultExpr(NameResult *pr) {
- ENode *expr;
-
- if (pr->obj_10) {
- switch (pr->obj_10->otype) {
- case OT_OBJECT:
- CClass_CheckObjectAccess(pr->bcl_18, OBJECT(pr->obj_10));
- return create_objectnode(OBJECT(pr->obj_10));
- case OT_ENUMCONST:
- CClass_CheckEnumAccess(pr->bcl_18, OBJ_ENUM_CONST(pr->obj_10));
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = OBJ_ENUM_CONST(pr->obj_10)->type;
- expr->data.intval = OBJ_ENUM_CONST(pr->obj_10)->val;
- return expr;
- case OT_MEMBERVAR:
- CError_Error(CErrorStr221);
- return nullnode();
- default:
- CError_FATAL(1268);
- }
- }
-
- if (pr->nsol_14) {
- expr = CExpr_NewENode(EOBJLIST);
- expr->rtype = OBJECT(pr->nsol_14->object)->type;
- expr->data.objlist.list = pr->nsol_14;
- return expr;
- }
-
- CError_FATAL(1278);
- return NULL;
-}
-
-static Type *CExpr_NewPTMType(EMemberInfo *member, Object *obj) {
- TypeMemberPointer *ptm;
- TypeMemberFunc *tmethod;
- BClassList *path;
-
- ptm = galloc(sizeof(TypeMemberPointer));
- memclrw(ptm, sizeof(TypeMemberPointer));
- ptm->type = TYPEMEMBERPOINTER;
-
- if (member->list->object->otype == OT_MEMBERVAR) {
- path = member->path;
- while (path->next)
- path = path->next;
- ptm->size = 4;
- ptm->ty2 = path->type;
- ptm->ty1 = OBJ_MEMBER_VAR(member->list->object)->type;
- } else {
- if (!obj) {
- CError_ASSERT(1306, member->list->object->otype == OT_OBJECT);
- obj = OBJECT(member->list->object);
- CError_ASSERT(1308, IS_TYPE_FUNC(obj->type));
- }
-
- tmethod = galloc(sizeof(TypeMemberFunc));
- memclrw(tmethod, sizeof(TypeMemberFunc));
- *tmethod = *TYPE_METHOD(obj->type);
-
- CError_ASSERT(1312, tmethod->args);
-
- tmethod->args = tmethod->args->next;
- CDecl_MakePTMFuncType(TYPE_FUNC(tmethod));
- tmethod->flags &= ~FUNC_DEFINED;
-
- ptm->size = 12;
- ptm->ty2 = TYPE(tmethod->theclass);
- ptm->ty1 = TYPE(tmethod);
- }
-
- return TYPE(ptm);
-}
-
-static ENode *CExpr_ParseNameResultExpr(NameResult *pr, ENode *expr, Boolean flag1, Boolean flag2) {
- ENode *result;
- ENode *ta_expr;
- ObjEnumConst *oec;
- TemplateAction *act;
- EMemberInfo *member;
- NameSpaceObjectList *list;
- Object *obj;
- TypeFunc *tfunc;
- SInt32 val;
-
- if (pr->type) {
- if (copts.cplusplus) {
- if (IS_TYPE_TEMPLATE(pr->type)) {
- if (TYPE_TEMPLATE(pr->type)->dtype == TEMPLDEP_ARGUMENT && TYPE_TEMPLATE(pr->type)->u.pid.type == TPT_NONTYPE) {
- result = CExpr_NewTemplDepENode(TDE_PARAM);
- result->data.templdep.u.pid = TYPE_TEMPLATE(pr->type)->u.pid;
- tk = lex();
- return result;
- }
- if (TYPE_TEMPLATE(pr->type)->dtype == TEMPLDEP_QUALNAME && !pr->x20) {
- result = CExpr_NewTemplDepENode(TDE_QUALNAME);
- result->data.templdep.u.qual.type = TYPE_TEMPLATE(pr->type)->u.qual.type;
- result->data.templdep.u.qual.name = TYPE_TEMPLATE(pr->type)->u.qual.name;
- tk = lex();
- return result;
- }
- }
- tk = lex();
- return CExpr_ParseExplicitConversion(pr->type, pr->qual);
- }
- CError_ErrorSkip(CErrorStr141);
- tk = lex();
- return nullnode();
- }
-
- if (pr->obj_10) {
- switch (pr->obj_10->otype) {
- case OT_OBJECT:
- if (OBJECT(pr->obj_10)->nspace && OBJECT(pr->obj_10)->nspace->theclass && (OBJECT(pr->obj_10)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- result = CExpr_NewTemplDepENode(TDE_OBJ);
- result->data.templdep.u.obj = OBJECT(pr->obj_10);
- tk = lex();
- return result;
- }
- if (!expr || !IS_TEMPL_FUNC(OBJECT(pr->obj_10)->type)) {
- if (!IS_TYPE_NONSTATIC_METHOD(OBJECT(pr->obj_10)->type)) {
- tk = lex();
- if (tk == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr)))
- return ta_expr;
- if (OBJECT(pr->obj_10)->datatype == DLOCAL && OBJECT(pr->obj_10)->u.var.info->func != cscope_currentfunc) {
- CError_Error(CErrorStr330);
- return nullnode();
- }
- if (OBJECT(pr->obj_10)->datatype == DEXPR) {
- result = CInline_CopyExpression(OBJECT(pr->obj_10)->u.expr, CopyMode0);
- if (IS_TYPE_POINTER_ONLY(result->rtype) && ENODE_IS(result, EINTCONST)) {
- result = makemonadicnode(result, ETYPCON);
- result->data.monadic->rtype = TYPE(&stunsignedlong);
- }
- return result;
- }
- CClass_CheckObjectAccess(pr->bcl_18, OBJECT(pr->obj_10));
- if (tk == '(' && flag2 && OBJECT(pr->obj_10)->datatype == DFUNC && copts.cplusplus && !pr->x1D && !IS_TYPEFUNC_METHOD(TYPE_FUNC(OBJECT(pr->obj_10)->type))) {
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(pr->obj_10)->type;
- result->data.objlist.list = galloc(sizeof(NameSpaceObjectList));
- result->data.objlist.list->next = pr->nsol_14;
- result->data.objlist.list->object = pr->obj_10;
- result->data.objlist.name = OBJECT(pr->obj_10)->name;
- return result;
- }
-
- result = create_objectnode(OBJECT(pr->obj_10));
- if (expr) {
- while (ENODE_IS(expr, EINDIRECT))
- expr = expr->data.monadic;
- switch (expr->type) {
- case EINTCONST:
- case EOBJREF:
- case EOBJLIST:
- break;
- default:
- result = makecommaexpression(expr, result);
- }
- }
- return result;
- }
- if (CClass_IsDestructor(OBJECT(pr->obj_10))) {
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
- if (!expr && (!cscope_currentfunc || !cscope_currentclass || !cscope_is_member_func)) {
- CError_Error(CErrorStr221);
- return nullnode();
- }
- if (pr->isambig)
- CError_Error(CErrorStr188);
-
- if ((expr = CExpr_GetClassAccessNode(pr->bcl_18, NULL, expr, OBJECT(pr->obj_10), pr->obj_10->access, 1))) {
- tk = lex();
- return CABI_DestroyObject(OBJECT(pr->obj_10), expr->data.monadic, 1, pr->x1D, 0);
- }
- }
- }
- break;
- case OT_ENUMCONST:
- CClass_CheckEnumAccess(pr->bcl_18, OBJ_ENUM_CONST(pr->obj_10));
- oec = OBJ_ENUM_CONST(pr->obj_10);
- if (CInt64_IsZero(&oec->val) && IS_TYPE_ENUM(oec->type) && TYPE_ENUM(oec->type)->nspace && TYPE_ENUM(oec->type)->nspace->theclass && (TYPE_ENUM(oec->type)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- val = 0;
- expr = NULL;
- for (act = TEMPL_CLASS(TYPE_ENUM(oec->type)->nspace->theclass)->actions; act; act = act->next) {
- if (act->type == TAT_ENUMERATOR) {
- if (act->u.enumerator.initexpr) {
- expr = act->u.enumerator.initexpr;
- val = 0;
- } else {
- val++;
- }
- if (act->u.enumerator.objenumconst == oec) {
- CError_ASSERT(1521, expr);
- expr = CInline_CopyExpression(expr, CopyMode0);
- if (val)
- expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), val), EADD);
- tk = lex();
- return expr;
- }
- }
- }
- }
- result = lalloc(sizeof(ENode));
- result->type = EINTCONST;
- result->cost = 0;
- result->flags = 0;
- result->rtype = OBJ_ENUM_CONST(pr->obj_10)->type;
- result->data.intval = OBJ_ENUM_CONST(pr->obj_10)->val;
- tk = lex();
- return result;
- case OT_MEMBERVAR:
- if (!flag1 || expr || !pr->x1D) {
- if (pr->isambig)
- CError_Error(CErrorStr188);
- result = checkreference(CExpr_MemberVarAccess(pr->bcl_18, OBJ_MEMBER_VAR(pr->obj_10), expr));
- tk = lex();
- return result;
- }
- break;
- default:
- CError_FATAL(1552);
- }
-
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
- member->path = pr->bcl_18;
- member->expr = expr;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
- if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) {
- CError_ASSERT(1564, ENODE_IS(ta_expr, EOBJLIST));
- member->list = ta_expr->data.objlist.list;
- member->templargs = ta_expr->data.objlist.templargs;
- } else {
- member->list = galloc(sizeof(NameSpaceObjectList));
- member->list->next = NULL;
- member->list->object = pr->obj_10;
- }
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
-
- if (pr->nsol_14) {
- if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) {
- CError_ASSERT(1591, ENODE_IS(ta_expr, EOBJLIST));
- for (list = ta_expr->data.objlist.list; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(OBJECT(list->object)->type)) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
-
- member->path = pr->bcl_18;
- member->expr = expr;
- member->list = ta_expr->data.objlist.list;
- member->templargs = ta_expr->data.objlist.templargs;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
- }
- return ta_expr;
- }
-
- for (list = pr->nsol_14; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(OBJECT(list->object)->type)) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
-
- member->path = pr->bcl_18;
- member->expr = expr;
- member->list = pr->nsol_14;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
- }
-
- if (tk == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr)))
- return ta_expr;
-
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(pr->nsol_14->object)->type;
- result->data.objlist.list = pr->nsol_14;
- if (tk == '(' && copts.cplusplus && flag2 && !pr->x1D && pr->nsol_14->object->otype == OT_OBJECT)
- result->data.objlist.name = OBJECT(pr->nsol_14->object)->name;
- return result;
- }
-
- if (pr->name_4) {
- if (copts.cplusplus && flag2) {
- if (lookahead() == '(') {
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = &stvoid;
- result->data.objlist.name = pr->name_4;
- tk = lex();
- return result;
- }
- CError_Error(CErrorStr140, pr->name_4->name);
- tk = lex();
- return nullnode();
- }
-
- if (lookahead() != '(') {
- CError_Error(CErrorStr140, pr->name_4->name);
- tk = lex();
- return nullnode();
- }
-
- if (copts.checkprotos)
- CError_Error(CErrorStr178);
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = TYPE(&stsignedint);
- tfunc->args = &oldstyle;
- CDecl_SetFuncFlags(tfunc, 0);
-
- obj = CParser_NewFunctionObject(NULL);
- obj->name = pr->name_4;
- obj->sclass = TK_EXTERN;
- obj->nspace = cscope_root;
- obj->type = TYPE(tfunc);
-
- CScope_AddGlobalObject(obj);
- tk = lex();
- return create_objectrefnode(obj);
- }
-
- CError_FATAL(1711);
- return NULL;
-}
-
-static ENode *CExpr_ParseRotate(Boolean is_right) {
- ENode *expr1;
- ENode *expr2;
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
-
- tk = lex();
- expr1 = assignment_expression();
-
- if (tk != ',') {
- CError_Error(CErrorStr116);
- return nullnode();
- }
-
- tk = lex();
- expr2 = assignment_expression();
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- if (!IS_TYPE_INT(expr1->rtype))
- expr1 = forceintegral(expr1);
- expr2 = integralpromote(expr2);
-
- tk = lex();
- if (iszero(expr1) || iszero(expr2))
- return expr1;
-
- return makediadicnode(expr1, expr2, is_right ? EROTR : EROTL);
-}
-
-static ENode *CExpr_ParseNextArg(void) {
- NameSpaceObjectList *list;
- NameResult pr;
- ENode *expr;
- SInt32 rounded_size;
-
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return nullnode();
- }
-
- list = CScope_FindObjectList(&pr, tkidentifier);
- if (!list) {
- CError_Error(CErrorStr140, tkidentifier->name);
- return nullnode();
- }
-
- if (list->object->otype != OT_OBJECT || OBJECT(list->object)->datatype != DLOCAL) {
- CError_Error(CErrorStr140, tkidentifier->name);
- return nullnode();
- }
-
- rounded_size = CMach_RoundedSizeOf(OBJECT(list->object));
- expr = CExpr_MakeObjRefNode(OBJECT(list->object), 1);
- expr = makediadicnode(expr, intconstnode(CABI_GetPtrDiffTType(), rounded_size), EADD);
- expr->rtype = TYPE(&void_ptr);
-
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- return expr;
- } else {
- tk = lex();
- return expr;
- }
-}
-
-static ENode *CExpr_ParseVecStep(void) {
- ENode *expr;
- Type *type;
- SInt32 value;
- DeclInfo di;
-
- expr = intconstnode(TYPE(&stsignedint), 0);
- if ((tk = lex()) == '(') {
- if (tk == '(' && islookaheaddeclaration()) {
- tk = lex();
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr121);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- type = di.thetype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
- } else {
- expr = unary_expression();
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EBITFIELD))
- CError_Error(CErrorStr144);
- type = expr->rtype;
- }
-
- CDecl_CompleteType(type);
- if (IS_TYPE_VECTOR(type)) {
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- value = 16;
- break;
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- value = 8;
- break;
- default:
- value = 4;
- }
- expr = intconstnode(TYPE(&stsignedint), value);
- } else {
- PPCError_Error(PPCErrorStr104, "vec_step", "vec_step", type, 0);
- }
- } else {
- CError_Error(CErrorStr114);
- }
-
- return expr;
-}
-
-static SInt32 CExpr_BuiltInComputeAlign(Type *type) {
- return CMach_GetTypeAlign(type);
-}
-
-static SInt32 CExpr_AtomTypeID(IntegralType what) {
- switch (what) {
- case IT_BOOL: return 1;
- case IT_CHAR: return 2;
- case IT_SCHAR: return 3;
- case IT_UCHAR: return 4;
- case IT_WCHAR_T: return 5;
- case IT_SHORT: return 6;
- case IT_USHORT: return 7;
- case IT_INT: return 8;
- case IT_UINT: return 9;
- case IT_LONG: return 10;
- case IT_ULONG: return 10;
- case IT_LONGLONG: return 12;
- case IT_ULONGLONG: return 13;
- case IT_FLOAT: return 14;
- case IT_SHORTDOUBLE: return 15;
- case IT_DOUBLE: return 16;
- case IT_LONGDOUBLE: return 17;
- case IT_17: return 32;
- case IT_18: return 33;
- case IT_19: return 34;
- case IT_20: return 35;
- case IT_21: return 36;
- case IT_22: return 37;
- case IT_23: return 38;
- case IT_24: return 39;
- default:
- CError_FATAL(1976);
- return 0;
- }
-}
-
-static SInt32 CExpr_BuiltInComputeType(Type *type) {
- switch (type->type) {
- case TYPEINT:
- return 0x100 | CExpr_AtomTypeID(TYPE_INTEGRAL(type)->integral);
- case TYPEFLOAT:
- return 0x200 | CExpr_AtomTypeID(TYPE_INTEGRAL(type)->integral);
- case TYPEENUM:
- return 0x400 | (CExpr_BuiltInComputeType(TYPE_ENUM(type)->enumtype) & 0xFF);
- case TYPEPOINTER:
- return 0x800;
- case TYPEARRAY:
- return 0x1000;
- case TYPESTRUCT:
- return 0x2000;
- case TYPECLASS:
- return 0x2000;
- case TYPEMEMBERPOINTER:
- return 0x4000;
- case TYPEFUNC:
- return 0x8000;
- default:
- CError_Error(CErrorStr146);
- case TYPEVOID:
- return 0;
- }
-}
-
-static SInt32 CExpr_BuiltInClassifyType(Type *type) {
- switch (type->type) {
- case TYPEVOID: return 0;
- case TYPEFUNC: return 10;
- case TYPEENUM: return 3;
- case TYPEINT: return 1;
- case TYPEFLOAT: return 8;
- case TYPEPOINTER: case TYPEMEMBERPOINTER: return 5;
- case TYPEARRAY: return 14;
- case TYPESTRUCT: return 12;
- case TYPECLASS: return 12;
- case TYPEBITFIELD: return -1;
- case TYPETEMPLATE: return -1;
- default: return -1;
- }
-}
-
-static SInt32 CExpr_BuiltInComputeVArgType(Type *type) {
- switch (type->type) {
- case TYPEINT:
- case TYPEENUM:
- return 0;
- case TYPEFLOAT:
- return 1;
- default:
- return 2;
- }
-}
-
-static Type *CExpr_ParseTypeExpression(Boolean *outflag) {
- ENode *expr;
- Type *type;
- DeclInfo di;
-
- tk = lex();
- if (tk == '(' && islookaheaddeclaration()) {
- tk = lex();
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr121);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- type = di.thetype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
- } else {
- expr = unary_expression();
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EBITFIELD))
- CError_Error(CErrorStr144);
-
- if (outflag)
- *outflag = ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval);
-
- type = expr->rtype;
- }
-
- CDecl_CompleteType(type);
- return type;
-}
-
-static ENode *CExpr_ParseBuiltin(SInt32 (*parser)(Type *)) {
- ENode *expr;
- expr = intconstnode(TYPE(&stsignedint), 0);
- CInt64_SetLong(&expr->data.intval, parser(CExpr_ParseTypeExpression(NULL)));
- return expr;
-}
-
-static ENode *CExpr_ParseBuiltin_isintconst(void) {
- ENode *expr;
- expr = intconstnode(TYPE(&stsignedint), 0);
-
- tk = lex();
- if (tk != '(')
- CError_ErrorSkip(CErrorStr121);
- else
- tk = lex();
-
- if (ENODE_IS(expression(), EINTCONST))
- CInt64_SetLong(&expr->data.intval, 1);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- return expr;
-}
-
-static ENode *primary_expression(Boolean flag) {
- NameResult pr;
- ENode *expr;
-
- switch (tk) {
- case TK_TRUE:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&stbool);
- CInt64_SetULong(&expr->data.intval, 1);
- tk = lex();
- return expr;
- case TK_FALSE:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&stbool);
- CInt64_SetULong(&expr->data.intval, 0);
- tk = lex();
- return expr;
- case TK_INTCONST:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = atomtype();
- expr->data.intval = tkintconst;
- tk = lex();
- return expr;
- case TK_FLOATCONST:
- expr = lalloc(sizeof(ENode));
- expr->type = EFLOATCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = atomtype();
- expr->data.floatval = tkfloatconst;
- tk = lex();
- return expr;
- case TK_STRING:
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewArrayType(ispascalstring ? TYPE(&stunsignedchar) : TYPE(&stchar), tksize);
- expr->data.string.size = tksize;
- expr->data.string.data = tkstring;
- expr->data.string.ispascal = ispascalstring;
- if (copts.const_strings)
- expr->flags = ENODE_FLAG_CONST;
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- tk = lex();
- return expr;
- case TK_STRING_WIDE:
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewArrayType(CParser_GetWCharType(), tksize);
- expr->data.string.size = tksize;
- expr->data.string.data = tkstring;
- expr->data.string.ispascal = ispascalstring;
- if (copts.const_strings)
- expr->flags = ENODE_FLAG_CONST;
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- tk = lex();
- return expr;
- case TK_THIS:
- case TK_SELF:
- expr = CClass_CreateThisSelfExpr();
- if (!expr)
- expr = nullnode();
- tk = lex();
- return expr;
- case TK_AT_SELECTOR:
- return CObjC_ParseSelectorExpression();
- case TK_AT_ENCODE:
- return CObjC_ParseEncodeExpression();
- case TK_AT_PROTOCOL:
- return CObjC_ParseProtocolExpression();
- case '@':
- if (copts.objective_c)
- return CObjC_ParseAtExpression();
- break;
- case '(':
- tk = lex();
- expr = s_expression();
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
- if (ENODE_IS(expr, EASS))
- expr->flags = expr->flags | ENODE_FLAG_80;
- return expr;
- case '[':
- if (copts.objective_c)
- return CObjC_ParseMessageExpression();
- break;
- case TK_IDENTIFIER:
- if (tkidentifier->name[0] == '_' && tkidentifier->name[1] == '_') {
- if (!strcmp(tkidentifier->name, "__builtin_align"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeAlign);
- if (!strcmp(tkidentifier->name, "__builtin_ntype"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeType);
- if (!strcmp(tkidentifier->name, "__builtin_type") || !strcmp(tkidentifier->name, "__builtin_vargtype"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeVArgType);
- if (!strcmp(tkidentifier->name, "__builtin_classify_type"))
- return CExpr_ParseBuiltin(CExpr_BuiltInClassifyType);
- if (!strcmp(tkidentifier->name, "__builtin_next_arg"))
- return CExpr_ParseNextArg();
- }
- if (copts.altivec_model && !strcmp("vec_step", tkidentifier->name))
- return CExpr_ParseVecStep();
- case '~':
- case TK_OPERATOR:
- case TK_INHERITED:
- case TK_COLON_COLON:
- if (CScope_ParseExprName(&pr))
- return CExpr_ParseNameResultExpr(&pr, NULL, flag, 1);
- tk = lex();
- return nullnode();
- }
-
- CError_ErrorSkip(CErrorStr141);
- return nullnode();
-}
-
-static ENode *CExpr_SimpleExplicitConversion(void) {
- DeclInfo di;
-
- memclrw(&di, sizeof(DeclInfo));
-
- if (!copts.cpp_extensions && tk != TK_UU_TYPEOF_UU && tk != TK_TYPENAME && lookahead() != '(')
- CError_Error(CErrorStr114);
-
- CParser_GetDeclSpecs(&di, 0);
- return CExpr_ParseExplicitConversion(di.thetype, di.qual);
-}
-
-static ENode *CExpr_NewPTMFCall(void) {
- tk = lex();
- CExpr_ScanExpressionList(1);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- } else {
- CError_FATAL(2465);
- return nullnode();
- }
-}
-
-static ENode *call_ptmf(ENode *expr) {
- Type *rettype;
- ENodeList *args;
- ENodeList *list1;
- ENodeList *list2;
- Object *callobj;
-
- rettype = TYPE_FUNC(TPTR_TARGET(expr->data.mfpointer.mfpointer->rtype))->functype;
- tk = lex();
- args = CExpr_ScanExpressionList(1);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- if (IS_TYPE_STRUCT(rettype) || IS_TYPE_CLASS(rettype) || IS_TYPE_12BYTES_MEMBERPOINTER(rettype))
- callobj = rt_ptmf_scall4;
- else
- callobj = rt_ptmf_scall;
-
- list1 = lalloc(sizeof(ENodeList));
- list1->next = args;
- list1->node = expr->data.mfpointer.accessnode->data.monadic;
-
- list2 = lalloc(sizeof(ENodeList));
- list2->next = list1;
- list2->node = expr->data.mfpointer.mfpointer->data.monadic;
-
- if (!copts.old_argmatch) {
- CError_ASSERT(2568, IS_TYPE_POINTER_ONLY(list2->node->rtype));
- list2->node->rtype = TYPE(&void_ptr);
- }
-
- expr = CExpr_GenericPtmfCall(
- callobj,
- TYPE_FUNC(TPTR_TARGET(expr->data.mfpointer.mfpointer->rtype)),
- list2);
- tk = lex();
- return expr;
-}
-
-static ENode *CExpr_DummyDestr(ENode *expr) {
- SInt32 state;
- NameResult pr;
- DeclInfo di;
- NameSpace *nspace;
-
- CPrep_TokenStreamGetState(&state);
- nspace = cscope_current;
- if ((tk = lex()) == TK_COLON_COLON) {
- nspace = cscope_root;
- tk = lex();
- } else if (tk != '~' && tk != TK_IDENTIFIER && !(tk >= TK_AUTO && tk <= TK_BYREF)) {
- CPrep_TokenStreamSetCurState(&state);
- return NULL;
- }
-
-loop:
- if (tk == '~')
- goto is_tilde;
- if (tk == TK_IDENTIFIER) {
- if (CScope_FindTypeName(nspace, tkidentifier, &pr)) {
- tk = lex();
- if (pr.nspace_0) {
- if (tk == TK_COLON_COLON) {
- tk = lex();
- nspace = pr.nspace_0;
- goto loop;
- }
- } else if (IS_TYPE_CLASS(pr.type) && tk == TK_COLON_COLON) {
- tk = lex();
- nspace = TYPE_CLASS(pr.type)->nspace;
- goto loop;
- } else {
- if (!is_typesame(pr.type, expr->rtype))
- CError_Error(CErrorStr146);
- if (tk == TK_COLON_COLON && ((tk = lex()) == '~') && ((tk = lex()) == TK_IDENTIFIER)) {
- parse_dtor:
- if (CScope_FindTypeName(nspace, tkidentifier, &pr) && !pr.nspace_0) {
- if (!is_typesame(pr.type, expr->rtype))
- CError_Error(CErrorStr146);
- tk = lex();
- goto parsed;
- }
- }
- }
- }
- } else if (tk >= TK_AUTO && tk <= TK_BYREF) {
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass || di.qual || !is_typesame(di.thetype, expr->rtype))
- CError_Error(CErrorStr146);
- if (tk == TK_COLON_COLON && ((tk = lex()) == '~')) {
- is_tilde:
- if ((tk = lex()) == TK_IDENTIFIER)
- goto parse_dtor;
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass || !is_typesame(di.thetype, expr->rtype))
- CError_Error(CErrorStr146);
- goto parsed;
- }
- }
-
- CError_Error(CErrorStr141);
- return NULL;
-
-parsed:
- if (tk == '(') {
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- CError_Error(CErrorStr114);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = &stvoid;
- return expr;
-}
-
-static ENode *postfix_expression(Boolean flag) {
- NameResult pr;
- Conversion conv;
- ENode *expr;
- ENode *subexpr;
- ENode *funcexpr;
- ENodeList *args;
- ENode *copy;
- ENode *tmp;
- StructMember *member;
-
- if (copts.cplusplus) {
- switch (tk) {
- case TK_VOID:
- case TK_CHAR:
- case TK_SHORT:
- case TK_INT:
- case TK_LONG:
- case TK_FLOAT:
- case TK_DOUBLE:
- case TK_SIGNED:
- case TK_UNSIGNED:
- case TK_UNK_113:
- case TK_UNK_114:
- case TK_UNK_115:
- case TK_UNK_116:
- case TK_UNK_117:
- case TK_UNK_118:
- case TK_UNK_119:
- case TK_UNK_11A:
- case TK_UU_TYPEOF_UU:
- case TK_BOOL:
- case TK_WCHAR_T:
- case TK_TYPENAME:
- expr = CExpr_SimpleExplicitConversion();
- break;
- default:
- expr = primary_expression(flag);
- break;
- case TK_CONST_CAST:
- expr = CRTTI_Parse_const_cast();
- break;
- case TK_DYNAMIC_CAST:
- expr = CRTTI_Parse_dynamic_cast();
- break;
- case TK_REINTERPRET_CAST:
- expr = CRTTI_Parse_reinterpret_cast();
- break;
- case TK_STATIC_CAST:
- expr = CRTTI_Parse_static_cast();
- break;
- case TK_TYPEID:
- expr = CRTTI_ParseTypeID();
- break;
- }
- } else {
- expr = primary_expression(flag);
- }
-
-loop:
- switch (tk) {
- case '[':
- expr = pointer_generation(expr);
- tk = lex();
- subexpr = expression();
- if (copts.cplusplus && CExpr_CheckOperator('[', expr, subexpr, &conv)) {
- if ((expr = conv.x0)) {
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- goto loop;
- }
-
- CError_ASSERT(2753, expr = conv.left);
- CError_ASSERT(2754, subexpr = conv.right);
- }
-
- if (IS_TYPE_POINTER(expr->rtype)) {
- expr = padd(expr, subexpr);
- } else if (IS_TYPE_POINTER(subexpr->rtype)) {
- expr = padd(subexpr, expr);
- } else {
- CError_Error(CErrorStr148);
- goto dont_do_indirect;
- }
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- dont_do_indirect:
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- goto loop;
-
- case '(':
- funcexpr = CExpr_PointerGeneration(expr);
- if (copts.cplusplus) {
- if (CExpr_CheckOperator('(', funcexpr, NULL, &conv)) {
- CError_ASSERT(2775, expr = conv.x0);
- goto loop;
- }
- if (ENODE_IS(funcexpr, EMFPOINTER)) {
- expr = checkreference(call_ptmf(funcexpr));
- goto loop;
- }
- }
-
- tk = lex();
- args = CExpr_ScanExpressionList(1);
- if (tk != ')')
- CError_Error(CErrorStr115);
-
- if (ENODE_IS(funcexpr, ETEMPLDEP)) {
- expr = CExpr_NewENode(EFUNCCALL);
- expr->rtype = &sttemplexpr;
- expr->data.funccall.funcref = funcexpr;
- expr->data.funccall.args = args;
- expr->data.funccall.functype = &rt_func;
- tk = lex();
- } else {
- expr = checkreference(CExpr_MakeFunctionCall(funcexpr, args));
- tk = lex();
- }
- goto loop;
-
- case TK_ARROW:
- expr = pointer_generation(expr);
- if (copts.cplusplus) {
- while (IS_TYPE_CLASS(expr->rtype) && CExpr_CheckOperator(TK_ARROW, expr, NULL, &conv)) {
- CError_ASSERT(2810, subexpr = conv.x0);
- expr = pointer_generation(subexpr);
- }
- }
-
- if (!IS_TYPE_POINTER(expr->rtype)) {
- CError_ErrorSkip(CErrorStr148);
- return expr;
- }
-
- if (copts.cplusplus && copts.objective_c && CObjC_IsType_id(expr->rtype)) {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- if ((subexpr = CObjC_CheckModernSendMessage(NULL, expr)))
- return subexpr;
- } else {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- }
- case '.':
- expr = pointer_generation(expr);
- if (IS_TYPE_CLASS(expr->rtype)) {
- CDecl_CompleteType(expr->rtype);
- if (TYPE_CLASS(expr->rtype)->objcinfo && copts.cplusplus && (subexpr = CObjC_CheckModernSendMessage(TYPE_CLASS(expr->rtype), expr)))
- return subexpr;
-
- if (!(TYPE_CLASS(expr->rtype)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, expr->rtype, 0);
-
- if ((tk = lex()) == TK_TEMPLATE && (tk = lex()) != TK_IDENTIFIER)
- CError_Error(CErrorStr107);
-
- if (CScope_ParseMemberName(TYPE_CLASS(expr->rtype), &pr, 0)) {
- if (pr.x1C) {
- if ((tk = lex()) == '(') {
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- CError_Error(CErrorStr114);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = &stvoid;
- } else {
- expr = checkreference(CExpr_ParseNameResultExpr(&pr, expr, 0, 0));
- }
- }
- goto loop;
- }
- if (!IS_TYPE_STRUCT(expr->rtype) || TYPE_STRUCT(expr->rtype)->stype > STRUCT_TYPE_MAX) {
- if (copts.cplusplus && (subexpr = CExpr_DummyDestr(expr)))
- return subexpr;
- CError_ErrorSkip(CErrorStr149);
- return expr;
- }
- if (!ENODE_IS(expr, EINDIRECT)) {
- subexpr = CExpr_NewETEMPNode(expr->rtype, 1);
- copy = lalloc(sizeof(ENode));
- *copy = *subexpr;
-
- tmp = makemonadicnode(subexpr, EINDIRECT);
- tmp->rtype = expr->rtype;
-
- tmp = makediadicnode(tmp, expr, EASS);
- tmp = makediadicnode(tmp, copy, ECOMMA);
- tmp->rtype = copy->rtype;
-
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = expr->rtype;
- expr = tmp;
- }
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return expr;
- }
-
- member = ismember(TYPE_STRUCT(expr->rtype), tkidentifier);
- if (!member) {
- if (!expr->rtype->size)
- CError_Error(CErrorStr136, expr->rtype, 0);
- else
- CError_Error(CErrorStr150, tkidentifier->name);
- return expr;
- }
-
- if (!IS_TYPE_POINTER(expr->data.monadic->rtype)) {
- CError_ErrorSkip(CErrorStr149);
- return expr;
- }
-
- expr = checkreference(CClass_AccessMember(expr, member->type, member->qual, member->offset));
- tk = lex();
- goto loop;
-
- case TK_INCREMENT:
- tmp = pointer_generation(expr);
- if (copts.cplusplus && CExpr_CheckOperator(TK_INCREMENT, tmp, nullnode(), &conv)) {
- if ((expr = conv.x0)) {
- tk = lex();
- goto loop;
- }
- CError_ASSERT(2952, tmp = conv.left);
- }
- tmp = CExpr_LValue(tmp, 1, 1);
- if (tmp->rtype == TYPE(&stbool)) {
- expr = CExpr_TempModifyExpr(tmp);
- tk = lex();
- } else {
- checkadditive(tmp);
- expr = makemonadicnode(tmp, EPOSTINC);
- tk = lex();
- }
- goto loop;
-
- case TK_DECREMENT:
- tmp = pointer_generation(expr);
- if (copts.cplusplus && CExpr_CheckOperator(TK_DECREMENT, tmp, nullnode(), &conv)) {
- if ((expr = conv.x0)) {
- tk = lex();
- goto loop;
- }
- CError_ASSERT(2976, tmp = conv.left);
- }
- tmp = CExpr_LValue(tmp, 1, 1);
- checkadditive(tmp);
- expr = makemonadicnode(tmp, EPOSTDEC);
- tk = lex();
- goto loop;
- }
-
- return expr;
-}
-
-static ENode *CExpr_ParseSizeof(void) {
- Type *type;
- ENode *expr;
-
- type = CExpr_ParseTypeExpression(NULL);
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)
- CError_Error(CErrorStr286);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- expr = CExpr_NewTemplDepENode(TDE_SIZEOF);
- expr->data.templdep.u.typeexpr.type = type;
- return expr;
- }
-
- if (type->size == 0) {
- if (copts.gcc_extensions && (IS_TYPE_FUNC(type) || IS_TYPE_VOID(type)))
- return intconstnode(CABI_GetSizeTType(), 1);
-
- if (IS_TYPE_CLASS(type) || IS_TYPE_STRUCT(type))
- CError_Error(CErrorStr136, type, 0);
- else
- CError_Error(CErrorStr146);
- }
-
- return intconstnode(CABI_GetSizeTType(), type->size);
-}
-
-SInt32 scansizeof(void) {
- ENode *expr;
-
- expr = CExpr_ParseSizeof();
- if (!ENODE_IS(expr, EINTCONST)) {
- CError_Error(CErrorStr190);
- return 0;
- }
-
- return CInt64_GetULong(&expr->data.intval);
-}
-
-static ENode *CExpr_ParseAlignof(void) {
- Type *type;
- ENode *expr;
- SInt16 align;
-
- type = CExpr_ParseTypeExpression(NULL);
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)
- CError_Error(CErrorStr364);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- expr = CExpr_NewTemplDepENode(TDE_ALIGNOF);
- expr->data.templdep.u.typeexpr.type = type;
- return expr;
- }
-
- if (type->size == 0) {
- if (IS_TYPE_CLASS(type) || IS_TYPE_STRUCT(type))
- CError_Error(CErrorStr136, type, 0);
- else
- CError_Error(CErrorStr146);
- }
-
- align = CMach_GetTypeAlign(type);
- if (align == 0)
- align = 1;
-
- return intconstnode(CABI_GetSizeTType(), align);
-}
-
-SInt32 scanalignof(void) {
- ENode *expr;
-
- expr = CExpr_ParseAlignof();
- if (!ENODE_IS(expr, EINTCONST)) {
- CError_Error(CErrorStr190);
- return 0;
- }
-
- return CInt64_GetULong(&expr->data.intval);
-}
-
-static ENode *logicalexpression(ENode *expr) {
- if (copts.cplusplus && copts.booltruefalse)
- expr->rtype = TYPE(&stbool);
- else
- expr->rtype = TYPE(&stsignedint);
- return expr;
-}
-
-ENode *getnodeaddress(ENode *expr, Boolean flag) {
- ENode *result;
- Object *obj;
-
- if (!ENODE_IS(expr, EINDIRECT)) {
- expr = CExpr_LValue(expr, flag, flag);
- if (!ENODE_IS(expr, EINDIRECT)) {
- if (!flag)
- CError_Error(CErrorStr142);
- return nullnode();
- }
- } else {
- if (flag &&
- 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);
- }
-
- result = lalloc(sizeof(ENode));
- *result = *expr;
-restart:
- switch (result->data.monadic->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- result->type = ETYPCON;
- if (IS_TYPE_POINTER_ONLY(result->rtype))
- result->flags = TPTR_QUAL(result->rtype) & ENODE_FLAG_QUALS;
- result->rtype = CDecl_NewPointerType(result->rtype);
- return result;
- case EOBJREF:
- obj = result->data.monadic->data.objref;
- if (obj->datatype == DALIAS) {
- CExpr_AliasTransform(result->data.monadic);
- goto restart;
- }
- if (obj->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- obj->flags = obj->flags | OBJECT_FLAGS_2;
- if (flag && !copts.cplusplus && obj->sclass == TK_REGISTER)
- CError_Error(CErrorStr163);
- break;
- case EFUNCCALL:
- if (flag && !IS_TYPE_POINTER_ONLY(result->data.monadic->data.funccall.functype->functype))
- CError_Warning(CErrorStr142);
- break;
- case EBITFIELD:
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- switch (result->rtype->type) {
- case TYPEPOINTER:
- result->data.monadic->rtype = CDecl_NewPointerType(result->rtype);
- result->data.monadic->flags = result->flags;
- break;
- default:
- result->data.monadic->rtype = CDecl_NewPointerType(result->rtype);
- result->data.monadic->flags = result->flags;
- }
-
- return result->data.monadic;
-}
-
-static ENode *CExpr_MakeStaticMemberList(NameSpaceObjectList *list) {
- NameSpaceObjectList *newlist;
- NameSpaceObjectList *n;
- ENode *result;
-
- newlist = NULL;
- while (list) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_STATIC_METHOD(OBJECT(list->object)->type)) {
- n = galloc(sizeof(NameSpaceObjectList));
- *n = *list;
- n->next = newlist;
- newlist = n;
- }
- list = list->next;
- }
-
- if (!newlist) {
- CError_Warning(CErrorStr331);
- return nullnode();
- }
-
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(newlist->object)->type;
- result->data.objlist.list = newlist;
- return result;
-}
-
-static ENode *CExpr_MakePTDM(ENode *expr) {
- ENode *result;
-
- CError_ASSERT(3414, ENODE_IS(expr, EMEMBER) && expr->data.emember->list->object->otype == OT_MEMBERVAR);
-
- result = nullnode();
- result->rtype = CExpr_NewPTMType(expr->data.emember, NULL);
- CInt64_SetLong(&result->data.intval, OBJ_MEMBER_VAR(expr->data.emember->list->object)->offset + 1);
- return result;
-}
-
-ENode *getpointertomemberfunc(ENode *expr, Type *type, Boolean flag) {
- NameSpaceObjectList *list;
- Object *obj;
- Object *dataobj;
- Type *ptmtype;
- TypeMemberFunc *tmethod;
- OLinkList *olist;
- SInt32 data[3];
-
- CError_ASSERT(3442, ENODE_IS(expr, EMEMBER));
-
- if (expr->data.emember->expr && !copts.cpp_extensions)
- CError_Error(CErrorStr141);
-
- if (!copts.cpp_extensions) {
- if (!(expr->data.emember->x11 && expr->data.emember->pr_1D)) {
- if (type && IS_TYPE_MEMBERPOINTER(type))
- CError_Warning(CErrorStr331);
- }
- }
-
- if (expr->data.emember->list->next) {
- if (type) {
- if (IS_TYPE_MEMBERPOINTER(type)) {
- type = TYPE_MEMBER_POINTER(type)->ty1;
- for (list = expr->data.emember->list; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && is_memberpointerequal(OBJECT(list->object)->type, type)) {
- obj = OBJECT(list->object);
- break;
- }
- }
- if (!list) {
- CError_Error(CErrorStr146);
- return nullnode();
- }
- } else {
- return CExpr_MakeStaticMemberList(expr->data.emember->list);
- }
- } else {
- obj = OBJECT(expr->data.emember->list->object);
- }
- } else {
- obj = OBJECT(expr->data.emember->list->object);
- }
-
- while (obj->datatype == DALIAS)
- obj = obj->u.alias.object;
-
- CError_ASSERT(3503, obj->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(obj->type));
-
- if (TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)
- CError_Error(CErrorStr190);
-
- ptmtype = CExpr_NewPTMType(expr->data.emember, obj);
- tmethod = TYPE_METHOD(obj->type);
- dataobj = CParser_NewGlobalDataObject(NULL);
- dataobj->name = CParser_GetUniqueName();
- dataobj->nspace = cscope_root;
- dataobj->type = ptmtype;
- dataobj->sclass = TK_STATIC;
-
- if (flag) {
- data[0] = 0;
- if (obj->datatype == DVFUNC) {
- olist = NULL;
- data[1] = tmethod->vtbl_index;
- data[2] = tmethod->theclass->vtable->offset;
- } else {
- data[1] = -1;
- data[2] = 0;
- olist = galloc(sizeof(OLinkList));
- olist->next = NULL;
- olist->obj = obj;
- olist->somevalue = 0;
- olist->offset = 8;
- }
- CInit_DeclareData(dataobj, data, olist, dataobj->type->size);
- }
-
- return create_objectnode(dataobj);
-}
-
-static ENode *getpointertomember(ENode *expr) {
- CError_ASSERT(3554, ENODE_IS(expr, EMEMBER));
-
- if (expr->data.emember->expr)
- CError_Error(CErrorStr141);
-
- expr->data.emember->x11 = 1;
- if (!expr->data.emember->list->next) {
- if (expr->data.emember->list->object->otype == OT_MEMBERVAR)
- return CExpr_MakePTDM(expr);
- else
- return getpointertomemberfunc(expr, NULL, 1);
- }
-
- return expr;
-}
-
-ENode *CExpr_New_ELOGNOT_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, ELOGNOT, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('!', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3593, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- expr = forceintegral(expr);
- break;
- case TYPEMEMBERPOINTER:
- expr = CExpr_ConvertToCondition(expr);
- break;
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-
- switch (expr->type) {
- case EINTCONST:
- expr->data.intval = CInt64_Not(expr->data.intval);
- break;
- case EFLOATCONST:
- expr->type = EINTCONST;
- CInt64_SetLong(&expr->data.intval, CMach_FloatIsZero(expr->data.floatval));
- break;
- default:
- expr = makemonadicnode(expr, ELOGNOT);
- }
-
- return logicalexpression(expr);
-}
-
-ENode *CExpr_New_EMONMIN_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, EMONMIN, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('-', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3652, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- expr = integralpromote(expr);
- if (ENODE_IS(expr, EINTCONST)) {
- expr->data.intval = CMach_CalcIntMonadic(expr->rtype, '-', expr->data.intval);
- return expr;
- }
- return makemonadicnode(expr, EMONMIN);
- case TYPEFLOAT:
- if (ENODE_IS(expr, EFLOATCONST)) {
- expr->data.floatval = CMach_CalcFloatMonadic(expr->rtype, '-', expr->data.floatval);
- return expr;
- }
- return CExpr_UnaryFloatExpression(makemonadicnode(expr, EMONMIN));
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-}
-
-ENode *CExpr_New_EBINNOT_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, EBINNOT, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('~', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3702, expr = conv.left);
- }
-
- expr = integralpromote(expr);
-
- if (ENODE_IS(expr, EINTCONST)) {
- expr->data.intval = CMach_CalcIntMonadic(expr->rtype, '~', expr->data.intval);
- return expr;
- }
- return makemonadicnode(expr, EBINNOT);
-}
-
-ENode *unary_expression(void) {
- ENode *expr;
- ENode *tmp;
- Conversion conv;
-
- switch (tk) {
- case TK_COLON_COLON:
- switch (lookahead()) {
- case TK_NEW:
- tk = lex();
- return scannew(1);
- case TK_DELETE:
- tk = lex();
- return scandelete(1);
- }
- return postfix_expression(0);
-
- case TK_NEW:
- return scannew(0);
- case TK_DELETE:
- return scandelete(0);
- case TK_INCREMENT:
- tk = lex();
- if (copts.cplusplus) {
- expr = pointer_generation(cast_expression());
- if (CExpr_CheckOperator(TK_INCREMENT, expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3748, expr = conv.left);
- }
- } else {
- expr = pointer_generation(unary_expression());
- }
- expr = CExpr_LValue(expr, 1, 1);
- if (expr->rtype == TYPE(&stbool)) {
- tmp = nullnode();
- tmp->rtype = TYPE(&stbool);
- CInt64_SetLong(&tmp->data.intval, 1);
- return makediadicnode(expr, tmp, EASS);
- } else {
- checkadditive(expr);
- return makemonadicnode(expr, EPREINC);
- }
- case TK_DECREMENT:
- tk = lex();
- if (copts.cplusplus) {
- expr = pointer_generation(cast_expression());
- if (CExpr_CheckOperator(TK_DECREMENT, expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3776, expr = conv.left);
- }
- } else {
- expr = pointer_generation(unary_expression());
- }
- expr = CExpr_LValue(expr, 1, 1);
- checkadditive(expr);
- return makemonadicnode(expr, EPREDEC);
-
- case '&':
- if (copts.cplusplus) {
- switch ((tk = lex())) {
- case TK_IDENTIFIER:
- case TK_INHERITED:
- case TK_COLON_COLON:
- expr = postfix_expression(1);
- if (ENODE_IS(expr, EMEMBER))
- return getpointertomember(expr);
- break;
- default:
- expr = cast_expression();
- }
-
- if (CExpr_CheckOperator('&', expr, NULL, &conv)) {
- CError_ASSERT(3809, conv.x0);
- return conv.x0;
- }
- } else {
- tk = lex();
- expr = cast_expression();
- }
-
- if (copts.mpwc_relax && !copts.cplusplus && IS_TYPE_ARRAY(expr->rtype) && ENODE_IS(expr, EINDIRECT))
- return pointer_generation(expr);
- if (ENODE_IS(expr, EOBJLIST))
- return expr;
-
- if (IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
- tmp = CExpr_NewTemplDepENode(TDE_ADDRESS_OF);
- tmp->data.templdep.u.monadic = expr;
- return tmp;
- }
-
- return getnodeaddress(expr, 1);
-
- case '*':
- tk = lex();
- expr = pointer_generation(cast_expression());
- if (copts.cplusplus && CExpr_CheckOperator('*', expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3840, expr = conv.left);
- }
-
- if (!IS_TYPE_POINTER(expr->rtype)) {
- CError_Error(CErrorStr148);
- return expr;
- }
-
- tmp = makemonadicnode(expr, EINDIRECT);
- CDecl_CompleteType(tmp->rtype = TPTR_TARGET(tmp->rtype));
- return tmp;
-
- case '+':
- tk = lex();
- expr = pointer_generation(cast_expression());
- if (copts.cplusplus && CExpr_CheckOperator('+', expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3852, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- return integralpromote(expr);
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- return expr;
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-
- case '-':
- tk = lex();
- return CExpr_New_EMONMIN_Node(cast_expression());
- case '~':
- tk = lex();
- return CExpr_New_EBINNOT_Node(cast_expression());
- case '!':
- tk = lex();
- return CExpr_New_ELOGNOT_Node(cast_expression());
-
- case TK_SIZEOF:
- return CExpr_ParseSizeof();
- case TK_UU_ALIGNOF_UU:
- return CExpr_ParseAlignof();
-
- case TK_LOGICAL_AND:
- if (copts.ANSIstrict)
- break;
-
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return nullnode();
- }
-
- expr = lalloc(sizeof(ENode));
- expr->type = ELABEL;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&void_ptr);
- expr->data.label = findlabel();
- if (!expr->data.label) {
- expr->data.label = newlabel();
- expr->data.label->name = tkidentifier;
- expr->data.label->next = Labels;
- Labels = expr->data.label;
- }
- tk = lex();
- return expr;
- }
-
- return postfix_expression(0);
-}
-
-ENode *do_castnullcheck(ENode *condexpr, ENode *nullcheckexpr) {
- ENode *result;
-
- if (isnotzero(nullcheckexpr))
- return condexpr;
-
- result = lalloc(sizeof(ENode));
- *result = *condexpr;
- result->type = ENULLCHECK;
- result->data.nullcheck.nullcheckexpr = lalloc(sizeof(ENode));
- *result->data.nullcheck.nullcheckexpr = *nullcheckexpr;
- result->data.nullcheck.condexpr = condexpr;
- result->data.nullcheck.precompid = CParser_GetUniqueID();
-
- nullcheckexpr->type = EPRECOMP;
- nullcheckexpr->data.precompid = result->data.nullcheck.precompid;
-
- return result;
-}
-
-ENode *CExpr_SafeClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean pathcheckflag) {
- ENode *result;
-
- result = CClass_ClassPointerCast(expr, a, b, typconflag, 1, pathcheckflag);
- if (result != expr) {
- if (!(ENODE_IS(result, ETYPCON) && result->data.monadic == expr))
- result = do_castnullcheck(result, expr);
- }
- return result;
-}
-
-ENode *PointerToMemberCast(ENode *expr, TypeMemberPointer *tm1, TypeMemberPointer *tm2, Boolean flag) {
- BClassList *path;
- Boolean negate;
- short depth;
- Boolean isambig;
- SInt32 pathoffset;
- CInt64 pathoffset64;
- ENode *tmp;
-
- CError_ASSERT(3984, IS_TYPE_CLASS(tm1->ty2));
- CError_ASSERT(3985, IS_TYPE_CLASS(tm2->ty2));
-
- if (tm1->ty2 == tm2->ty2) {
- expr->rtype = TYPE(tm2);
- return expr;
- }
-
- negate = 0;
- path = CClass_GetBasePath(TYPE_CLASS(tm2->ty2), TYPE_CLASS(tm1->ty2), &depth, &isambig);
- if (!path) {
- path = CClass_GetBasePath(TYPE_CLASS(tm1->ty2), TYPE_CLASS(tm2->ty2), &depth, &isambig);
- if (!path)
- goto failed;
- negate = 1;
- }
-
- if (isambig)
- CError_Error(CErrorStr188);
-
- if ((pathoffset = CClass_GetPathOffset(path)) < 0)
- goto failed;
- if (negate)
- pathoffset = -pathoffset;
-
- if (flag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
-
- if (tm1->size != tm2->size) {
- failed:
- CError_Error(CErrorStr247, tm1, 0, tm2, 0);
- return nullnode();
- }
-
- if (!pathoffset) {
- expr->rtype = TYPE(tm2);
- return expr;
- }
-
- if (tm1->size == 4u) {
- if (ENODE_IS(expr, EINTCONST)) {
- if (!CInt64_IsZero(&expr->data.intval)) {
- CInt64_SetLong(&pathoffset64, pathoffset);
- expr->data.intval = CInt64_Add(expr->data.intval, pathoffset64);
- }
- expr->rtype = TYPE(tm2);
- return expr;
- } else {
- expr->rtype = TYPE(&stunsignedlong);
- tmp = intconstnode(TYPE(&stunsignedlong), pathoffset);
- tmp = makediadicnode(expr, tmp, EADD);
- tmp = makemonadicnode(tmp, ETYPCON);
- tmp->rtype = TYPE(tm2);
- return do_castnullcheck(tmp, expr);
- }
- } else {
- tmp = create_temp_node(TYPE(&ptmstruct));
- expr = getnodeaddress(expr, 0);
- tmp = funccallexpr(rt_ptmf_cast, intconstnode(TYPE(&stsignedlong), pathoffset), expr, tmp, NULL);
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = TYPE(tm2);
- return tmp;
- }
-}
-
-ENode *CExpr_MemberPointerConversion(ENode *expr, TypeMemberPointer *type, Boolean flag1) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
- if (IS_TYPE_FUNC(type->ty1))
- expr = create_objectnode(rt_ptmf_null);
- expr->rtype = TYPE(type);
- } else if (ENODE_IS(expr, EMEMBER)) {
- expr = getpointertomemberfunc(expr, TYPE(type), flag1);
- }
-
- return expr;
-}
-
-static ENode *CExpr_MemberPointerCast(ENode *expr, TypeMemberPointer *type, UInt32 qual) {
- if (!IS_TYPE_MEMBERPOINTER(expr->rtype))
- expr = CExpr_MemberPointerConversion(expr, type, 1);
-
- if (!IS_TYPE_MEMBERPOINTER(expr->rtype)) {
- CError_Error(CErrorStr164);
- return nullnode();
- }
-
- expr = PointerToMemberCast(expr, TYPE_MEMBER_POINTER(expr->rtype), type, 0);
- expr->flags = qual & ENODE_FLAG_QUALS;
- return expr;
-}
-
-ENode *do_typecast(ENode *expr, Type *type, UInt32 qual) {
- TypePointer *tptr;
- ENode *tmp;
- short flags;
-
- if (!copts.old_argmatch)
- return CExpr_Convert(expr, type, qual, 1, 0);
-
- if (copts.cpp_extensions && is_typesame(expr->rtype, type) && !ENODE_IS(expr, EOBJLIST)) {
- expr->rtype = type;
- expr->flags &= ~ENODE_FLAG_QUALS;
- expr->flags |= qual & ENODE_FLAG_QUALS;
- return expr;
- }
-
- switch (type->type) {
- case TYPEARRAY:
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return expr;
- case TYPEMEMBERPOINTER:
- if (!IS_TYPE_CLASS(expr->rtype))
- return CExpr_MemberPointerCast(expr, TYPE_MEMBER_POINTER(type), qual);
- }
-
- flags = qual & ENODE_FLAG_QUALS;
-
- if (ENODE_IS(expr, EOBJLIST))
- return CExpr_AssignmentPromotion(expr, type, qual & ENODE_FLAG_QUALS, 1);
-
- if (ENODE_IS(expr, EOBJREF) && IS_TYPE_NONSTATIC_METHOD(expr->data.objref->type)) {
- CError_Error(CErrorStr221);
- return nullnode();
- }
-
- if (type == &stvoid) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_REFERENCE(type)) {
- tmp = getnodeaddress(expr, 0);
- tptr = galloc(sizeof(TypePointer));
- *tptr = *TYPE_POINTER(type);
- tptr->qual &= ~Q_REFERENCE;
-
- tmp = do_typecast(tmp, TYPE(tptr), qual);
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = TPTR_TARGET(type);
- tmp->flags = flags;
- return tmp;
- }
-
- if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type)) {
- if (expr->rtype->size == 0)
- CDecl_CompleteType(expr->rtype);
-
- if (expr->rtype == type && !CClass_CopyConstructor(TYPE_CLASS(type)))
- return expr;
-
- if (user_assign_check(expr, type, qual, 1, 1, 1)) {
- assign_node->flags = flags;
- return assign_node;
- }
-
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return nullnode();
- }
-
- if (IS_TYPE_STRUCT(type) && copts.cplusplus && is_typesame(expr->rtype, type)) {
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (type == TYPE(&stbool)) {
- expr = CExpr_ConvertToBool(expr, 1);
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_ENUM(type)) {
- tmp = do_typecast(expr, TYPE_ENUM(type)->enumtype, qual);
- if (!ENODE_IS(tmp, EINTCONST))
- tmp = makemonadicnode(tmp, ETYPCON);
- tmp->rtype = type;
- tmp->flags = flags;
- return tmp;
- }
-
- if (IS_TYPE_INT_OR_FLOAT(type)) {
- if (ENODE_IS(expr, ETYPCON) && expr->rtype->type == type->type && expr->rtype->size == type->size) {
- if (is_unsigned(expr->rtype) == is_unsigned(type) && ENODE_QUALS(expr) == qual) {
- expr->rtype = type;
- expr->flags = expr->flags | ENODE_FLAG_80;
- return expr;
- }
- }
-
- if (IS_TYPE_ENUM(expr->rtype))
- expr = forceintegral(expr);
-
- if (IS_TYPE_INT_OR_FLOAT(expr->rtype)) {
- expr = promote(expr, type);
- expr->flags = flags;
- return expr;
- }
-
- if (!(IS_TYPE_POINTER_ONLY(expr->rtype) && !IS_TYPE_FLOAT(type)))
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
-
- if (ENODE_IS(expr, ETYPCON) && ENODE_IS(tmp = expr->data.monadic, EINTCONST)) {
- tmp->rtype = type;
- tmp->flags = flags;
- tmp->data.intval = CExpr_IntConstConvert(type, TYPE(&stunsignedlong), tmp->data.intval);
- return tmp;
- }
-
- if (type->size != 4) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_POINTER(type)) {
- if (IS_TYPE_POINTER(expr->rtype)) {
- if (IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(type)))
- expr = CExpr_SafeClassPointerCast(expr, TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), 1, 0);
-
- if (!ENODE_IS(expr, ETYPCON))
- expr = makemonadicnode(expr, ETYPCON);
-
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (!IS_TYPE_INT(expr->rtype)) {
- if (!IS_TYPE_ENUM(expr->rtype)) {
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return expr;
- }
- expr = forceintegral(expr);
- }
-
- if (expr->rtype->size != 4) {
- if (!ENODE_IS(expr, EINTCONST))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if ((tmp = CodeGen_HandleTypeCast(expr, type, qual)))
- return tmp;
-
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return nullnode();
-}
-
-static Boolean isvectorconst(ENode *node) {
- if (ENODE_IS3(node, ECOMMA, EINTCONST, EFLOATCONST))
- return 1;
- else
- return 0;
-}
-
-ENode *cast_expression(void) {
- ENode *expr;
- ENode *tmp;
- ENodeList *args;
- MWVector128 vec;
- DeclInfo di;
-
- if (!(tk == '(' && islookaheaddeclaration()))
- return unary_expression();
- tk = lex();
-
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- if (di.name)
- CError_Error(CErrorStr164);
-
- if (copts.altivec_model && tk == '(' && IS_TYPE_VECTOR(di.thetype)) {
- tk = lex();
- expr = s_expression();
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- if (CodeGen_CollapseVectorExpression(expr, &vec, di.thetype)) {
- tmp = lalloc(sizeof(ENode));
- tmp->type = EVECTOR128CONST;
- if ((tmp->cost = expr->cost) == 0)
- tmp->cost = 1;
- tmp->flags = ENODE_QUALS(expr);
- tmp->rtype = di.thetype;
- tmp->data.vector128val = vec;
- } else {
- tmp = makemonadicnode(expr, ETYPCON);
- }
- tmp->rtype = di.thetype;
- tmp->flags = expr->flags;
- return tmp;
- }
-
- if (tk == '{' && (!copts.ANSIstrict || copts.c9x) && !IS_TYPE_VECTOR(di.thetype))
- return CInit_AutoObject(NULL, di.thetype, di.qual);
-
- expr = cast_expression();
- if (copts.cplusplus && (CTemplTool_IsTemplateArgumentDependentType(di.thetype) ||
- CTemplTool_IsTemplateArgumentDependentExpression(expr))) {
- args = lalloc(sizeof(ENodeList));
- args->next = NULL;
- args->node = expr;
- return CExpr_TemplArgDepCast(di.thetype, di.qual, args);
- }
-
- if (!IS_TYPE_REFERENCE(di.thetype))
- expr = pointer_generation(expr);
- return do_typecast(expr, di.thetype, di.qual);
-}
-
-static ENode *pm_expression(void) {
- ENode *left;
- ENode *right;
- ENode *tmp;
- Type *type;
- UInt32 qual;
- short flags;
- Conversion conv;
-
- left = cast_expression();
-restart:
- switch (tk) {
- case TK_ARROW_STAR:
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(cast_expression());
-
- if (CExpr_CheckOperator(TK_ARROW_STAR, left, right, &conv)) {
- CError_ASSERT(4457, left = conv.x0);
- goto restart;
- }
-
- if (!IS_TYPE_POINTER(left->rtype)) {
- CError_Error(CErrorStr148);
- return left;
- }
-
- left = makemonadicnode(left, EINDIRECT);
- left->rtype = TPTR_TARGET(left->rtype);
- goto common_part;
- case TK_DOT_STAR:
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(cast_expression());
- if (!ENODE_IS(left, EINDIRECT)) {
- CError_Error(CErrorStr142);
- return left;
- }
- common_part:
- if (!IS_TYPE_CLASS(left->rtype)) {
- CError_Error(CErrorStr149);
- return left;
- }
- if (!IS_TYPE_MEMBERPOINTER(right->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- if (left->rtype != TYPE_MEMBER_POINTER(right->rtype)->ty2) {
- if (CClass_IsBaseClass(TYPE_CLASS(left->rtype), TYPE_CLASS(TYPE_MEMBER_POINTER(right->rtype)->ty2), NULL, 1, 1)) {
- left->data.monadic = CClass_ClassPointerCast(
- left->data.monadic,
- TYPE_CLASS(left->rtype),
- TYPE_CLASS(TYPE_MEMBER_POINTER(right->rtype)->ty2),
- 0, 1, 1);
- left->rtype = TYPE_MEMBER_POINTER(right->rtype)->ty2;
- } else {
- CError_Error(CErrorStr146);
- return left;
- }
- }
- type = CClass_CombineClassAccessQualifiers(
- TYPE_MEMBER_POINTER(right->rtype)->ty1,
- ENODE_QUALS(right),
- left->flags,
- &qual);
- flags = qual;
- if (!IS_TYPE_FUNC(type)) {
- if (!ENODE_IS(right, EINTCONST)) {
- if (!canadd(left->data.monadic, -1)) {
- left->data.monadic = makediadicnode(left->data.monadic, nullnode(), EADD);
- CInt64_SetLong(&left->data.monadic->data.diadic.right->data.intval, -1);
- optimizecomm(left->data.monadic);
- }
- right->rtype = TYPE(&stunsignedlong);
- left->data.monadic = makediadicnode(left->data.monadic, right, EADD);
- optimizecomm(left->data.monadic);
- } else {
- right->data.intval = CInt64_Sub(right->data.intval, cint64_one);
- if (!canadd2(left->data.monadic, right->data.intval)) {
- right->rtype = TYPE(&stunsignedlong);
- left->data.monadic = makediadicnode(left->data.monadic, right, EADD);
- optimizecomm(left->data.monadic);
- }
- }
-
- if (IS_TYPE_BITFIELD(type)) {
- left->data.monadic = makemonadicnode(left->data.monadic, EBITFIELD);
- left->data.monadic->rtype = type;
- left->rtype = TYPE_BITFIELD(type)->bitfieldtype;
- } else {
- left->rtype = type;
- }
- left->flags = flags;
- left = checkreference(left);
- goto restart;
- } else {
- CError_ASSERT(4535, ENODE_IS(right, EINDIRECT));
- tmp = lalloc(sizeof(ENode));
- tmp->type = EMFPOINTER;
- tmp->cost = 4;
- tmp->flags = 0;
- tmp->rtype = &stvoid;
- tmp->data.mfpointer.accessnode = left;
- tmp->data.mfpointer.mfpointer = right;
- return tmp;
- }
- default:
- return left;
- }
-}
-
-ENode *CExpr_New_EMUL_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EMUL, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('*', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4566, left = conv.left);
- CError_ASSERT(4567, right = conv.right);
- }
-
- return makemultnode(left, right);
-}
-
-ENode *CExpr_New_EDIV_Node(ENode *left, ENode *right, Boolean no_warning) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EDIV, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('/', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4592, left = conv.left);
- CError_ASSERT(4593, right = conv.right);
- }
-
- return makedivnode(left, right, no_warning);
-}
-
-ENode *CExpr_New_EMODULO_Node(ENode *left, ENode *right, Boolean no_warning) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EMODULO, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('%', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4618, left = conv.left);
- CError_ASSERT(4619, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right)) {
- if (!no_warning)
- CError_Warning(CErrorStr139);
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '%', right->data.intval);
- return left;
- }
-
- if (iszero(left))
- return makediadicnode(right, left, ECOMMA);
-
- if (CExpr_IsOne(right)) {
- right = nullnode();
- right->rtype = left->rtype;
- return makediadicnode(left, right, ECOMMA);
- }
-
- return makediadicnode(left, right, EMODULO);
-}
-
-ENode *CExpr_New_EADD_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EADD, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('+', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4665, left = conv.left);
- CError_ASSERT(4666, right = conv.right);
- }
-
- return makeaddnode(left, right);
-}
-
-ENode *CExpr_New_ESUB_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESUB, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('-', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4690, left = conv.left);
- CError_ASSERT(4691, right = conv.right);
- }
-
- return makesubnode(left, right);
-}
-
-ENode *CExpr_New_ESHL_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESHL, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_SHL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4715, left = conv.left);
- CError_ASSERT(4716, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
-
- if (iszero(left) || iszero(right)) {
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_SHL, right->data.intval);
- return left;
- }
-
- return makediadicnode(left, right, ESHL);
-}
-
-ENode *CExpr_New_ESHR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESHR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_SHR, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4752, left = conv.left);
- CError_ASSERT(4753, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
-
- if (iszero(left) || iszero(right)) {
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_SHR, right->data.intval);
- return left;
- }
-
- return makediadicnode(left, right, ESHR);
-}
-
-static ENode *pointercompare(ENodeType nt, ENode *left, ENode *right) {
- Type *ltype;
- Type *rtype;
-
- ltype = left->rtype;
- rtype = right->rtype;
- if (IS_TYPE_POINTER_ONLY(ltype) && IS_TYPE_POINTER_ONLY(rtype)) {
- ltype = TPTR_TARGET(left->rtype);
- rtype = TPTR_TARGET(right->rtype);
- if (IS_TYPE_CLASS(ltype) && IS_TYPE_CLASS(rtype)) {
- if (ltype != rtype) {
- if (ltype == TPTR_TARGET(left->rtype)) {
- if (CClass_IsBaseClass(TYPE_CLASS(ltype), TYPE_CLASS(rtype), NULL, 0, 1)) {
- left = CExpr_SafeClassPointerCast(left, TYPE_CLASS(ltype), TYPE_CLASS(rtype), 0, 1);
- } else if (CClass_IsBaseClass(TYPE_CLASS(rtype), TYPE_CLASS(ltype), NULL, 0, 1)) {
- right = CExpr_SafeClassPointerCast(right, TYPE_CLASS(rtype), TYPE_CLASS(ltype), 0, 1);
- } else {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- } else {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- }
- } else if (!is_typeequal(left->rtype, right->rtype)) {
- if (!copts.objective_c || !CObjC_IsCompatibleType(left->rtype, right->rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- }
- } else if (nt == EEQU || nt == ENOTEQU) {
- if (IS_TYPE_INT(ltype)) {
- if (!(ENODE_IS(left, EINTCONST) && CInt64_IsZero(&left->data.intval)))
- CError_Error(CErrorStr144);
- CError_ASSERT(4847, IS_TYPE_POINTER_ONLY(rtype));
- left->rtype = TYPE(&stunsignedlong);
- } else if (IS_TYPE_INT(rtype)) {
- if (!(ENODE_IS(right, EINTCONST) && CInt64_IsZero(&right->data.intval)))
- CError_Error(CErrorStr144);
- CError_ASSERT(4855, IS_TYPE_POINTER_ONLY(ltype));
- right->rtype = TYPE(&stunsignedlong);
- } else if (!is_typeequal(ltype, rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- } else {
- if (!is_typeequal(ltype, rtype))
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
-
- return logicalexpression(makediadicnode(left, right, nt));
-}
-
-static ENode *unsigncheck(ENode *expr, Boolean flag1, Boolean flag2) {
- if (is_unsigned(expr->data.diadic.left->rtype)) {
- if (ENODE_IS(expr->data.diadic.left, EINTCONST) && CInt64_IsZero(&expr->data.diadic.left->data.intval)) {
- flag1 = !flag1;
- } else if (!(ENODE_IS(expr->data.diadic.right, EINTCONST) && CInt64_IsZero(&expr->data.diadic.right->data.intval))) {
- return logicalexpression(expr);
- }
-
- if (flag1 && flag2) {
- expr->type = EEQU;
- return logicalexpression(expr);
- }
- if (!flag1 && !flag2) {
- expr->type = ENOTEQU;
- return logicalexpression(expr);
- }
- return CExpr_ConstResult(logicalexpression(expr), !flag1);
- }
- return logicalexpression(expr);
-}
-
-ENode *CExpr_New_ELESS_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELESS, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('<', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4929, left = conv.left);
- CError_ASSERT(4930, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ELESS, left, right);
-
- CExpr_CompareConvert(&left, "<", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '<', right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, '<', right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, ELESS), 1, 0);
- }
-
- return left;
-}
-
-ENode *CExpr_New_ELESSEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELESSEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LESS_EQUAL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4976, left = conv.left);
- CError_ASSERT(4977, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ELESSEQU, left, right);
-
- CExpr_CompareConvert(&left, "<=", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LESS_EQUAL, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LESS_EQUAL, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, ELESSEQU), 1, 1);
- }
-
- return left;
-}
-
-ENode *CExpr_New_EGREATER_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EGREATER, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('>', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5023, left = conv.left);
- CError_ASSERT(5024, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EGREATER, left, right);
-
- CExpr_CompareConvert(&left, ">", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '>', right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, '>', right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, EGREATER), 0, 0);
- }
-
- return left;
-}
-
-ENode *CExpr_New_EGREATEREQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EGREATEREQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_GREATER_EQUAL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5070, left = conv.left);
- CError_ASSERT(5071, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EGREATEREQU, left, right);
-
- CExpr_CompareConvert(&left, ">=", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_GREATER_EQUAL, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_GREATER_EQUAL, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, EGREATEREQU), 0, 1);
- }
-
- return left;
-}
-
-ENode *memberpointercompare(ENodeType nt, ENode *left, ENode *right) {
- Object *func;
- ENodeList *arg;
-
- if (!IS_TYPE_MEMBERPOINTER(left->rtype)) {
- if (!(IS_TYPE_INT(left->rtype) && ENODE_IS(left, EINTCONST) && CInt64_IsZero(&left->data.intval))) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else if (!IS_TYPE_MEMBERPOINTER(right->rtype)) {
- if (!(IS_TYPE_INT(right->rtype) && ENODE_IS(right, EINTCONST) && CInt64_IsZero(&right->data.intval))) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else if (!is_typeequal(left->rtype, right->rtype)) {
- left = PointerToMemberCast(left, TYPE_MEMBER_POINTER(left->rtype), TYPE_MEMBER_POINTER(right->rtype), 1);
- }
-
- if ((ENODE_IS(left, EINTCONST) || !IS_TYPE_FUNC(TYPE_MEMBER_POINTER(left->rtype)->ty1)) && (ENODE_IS(right, EINTCONST) || !IS_TYPE_FUNC(TYPE_MEMBER_POINTER(right->rtype)->ty1))) {
- left->rtype = TYPE(&stunsignedlong);
- right->rtype = TYPE(&stunsignedlong);
- return logicalexpression(makediadicnode(left, right, nt));
- }
-
- arg = lalloc(sizeof(ENodeList));
- if (ENODE_IS(left, EINTCONST) || ENODE_IS(right, EINTCONST)) {
- func = rt_ptmf_test;
- if (ENODE_IS(left, EINTCONST))
- arg->node = getnodeaddress(right, 0);
- else
- arg->node = getnodeaddress(left, 0);
- arg->next = NULL;
- } else {
- func = rt_ptmf_cmpr;
- arg->next = lalloc(sizeof(ENodeList));
- arg->node = getnodeaddress(left, 0);
- arg->next->node = getnodeaddress(right, 0);
- arg->next->next = NULL;
- }
-
- left = lalloc(sizeof(ENode));
- left->type = EFUNCCALL;
- left->rtype = TYPE(&stsignedlong);
- left->cost = 4;
- left->data.funccall.funcref = create_objectrefnode(func);
- left->data.funccall.args = arg;
- left->data.funccall.functype = TYPE_FUNC(func->type);
- left->flags = TYPE_FUNC(func->type)->qual & ENODE_FLAG_QUALS;
-
- if (nt == EEQU)
- left = makemonadicnode(left, ELOGNOT);
-
- return left;
-}
-
-ENode *CExpr_New_EEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_EQ, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5201, left = conv.left);
- CError_ASSERT(5202, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EEQU, left, right);
- if (IS_TYPE_MEMBERPOINTER(left->rtype) || IS_TYPE_MEMBERPOINTER(right->rtype))
- return memberpointercompare(EEQU, left, right);
-
- CExpr_CompareConvert(&left, "==", &right, 1);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LOGICAL_EQ, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->type = EINTCONST;
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LOGICAL_EQ, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = makediadicnode(left, right, EEQU);
- optimizecomm(left);
- }
-
- return logicalexpression(left);
-}
-
-ENode *CExpr_New_ENOTEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ENOTEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_NE, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5261, left = conv.left);
- CError_ASSERT(5262, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ENOTEQU, left, right);
- if (IS_TYPE_MEMBERPOINTER(left->rtype) || IS_TYPE_MEMBERPOINTER(right->rtype))
- return memberpointercompare(ENOTEQU, left, right);
-
- CExpr_CompareConvert(&left, "!=", &right, 1);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LOGICAL_NE, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LOGICAL_NE, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = makediadicnode(left, right, ENOTEQU);
- optimizecomm(left);
- }
-
- return logicalexpression(left);
-}
-
-ENode *CExpr_New_EAND_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EAND, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('&', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5321, left = conv.left);
- CError_ASSERT(5322, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(left) || CExpr_AllBitsSet(right))
- return left;
- if (iszero(right) || CExpr_AllBitsSet(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '&', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EAND);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_EXOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EXOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('^', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5360, left = conv.left);
- CError_ASSERT(5361, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right))
- return left;
- if (iszero(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '^', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EXOR);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_EOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('|', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5399, left = conv.left);
- CError_ASSERT(5400, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right) || CExpr_AllBitsSet(left))
- return left;
- if (iszero(left) || CExpr_AllBitsSet(right))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '|', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EOR);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_ELAND_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELAND, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_AND, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5438, left = conv.left);
- CError_ASSERT(5439, right = conv.right);
- }
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- left = CExpr_ConvertToCondition(left);
- break;
- default:
- CError_Error(CErrorStr144);
- left = nullnode();
- }
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- right = CExpr_ConvertToCondition(right);
- break;
- default:
- CError_Error(CErrorStr144);
- right = nullnode();
- }
-
- if (iszero(left)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- }
-
- if (isnotzero(left)) {
- if (iszero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- } else if (isnotzero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- } else {
- left = makemonadicnode(right, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- } else {
- if (isnotzero(right)) {
- left = makemonadicnode(left, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- } else if (iszero(right)) {
- right->type = EINTCONST;
- right->rtype = CParser_GetBoolType();
- CInt64_SetLong(&right->data.intval, 0);
- return makecommaexpression(left, right);
- } else {
- left = makediadicnode(left, right, ELAND);
- left->rtype = CParser_GetBoolType();
- return left;
- }
- }
-}
-
-ENode *CExpr_New_ELOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_OR, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5543, left = conv.left);
- CError_ASSERT(5544, right = conv.right);
- }
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- left = CExpr_ConvertToCondition(left);
- break;
- default:
- CError_Error(CErrorStr144);
- left = nullnode();
- }
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- right = CExpr_ConvertToCondition(right);
- break;
- default:
- CError_Error(CErrorStr144);
- right = nullnode();
- }
-
- if (isnotzero(left)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- }
-
- if (iszero(left)) {
- if (iszero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- } else if (isnotzero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- } else {
- left = makemonadicnode(right, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- } else {
- if (isnotzero(right)) {
- right->type = EINTCONST;
- right->rtype = CParser_GetBoolType();
- CInt64_SetLong(&right->data.intval, 1);
- } else if (iszero(right)) {
- left = makemonadicnode(left, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- left = makediadicnode(left, right, ELOR);
- left->rtype = CParser_GetBoolType();
- return left;
- }
-}
-
-ENode *CExpr_NewDyadicNode(ENode *left, ENodeType nt, ENode *right) {
- switch (nt) {
- default:
- CError_FATAL(5642);
- case EADD: return CExpr_New_EADD_Node(left, right);
- case ESUB: return CExpr_New_ESUB_Node(left, right);
- case EMUL: return CExpr_New_EMUL_Node(left, right);
- case EDIV: return CExpr_New_EDIV_Node(left, right, 1);
- case EMODULO: return CExpr_New_EMODULO_Node(left, right, 1);
- case EAND: return CExpr_New_EAND_Node(left, right);
- case EXOR: return CExpr_New_EXOR_Node(left, right);
- case EOR: return CExpr_New_EOR_Node(left, right);
- case ESHL: return CExpr_New_ESHL_Node(left, right);
- case ESHR: return CExpr_New_ESHR_Node(left, right);
- case ELESS: return CExpr_New_ELESS_Node(left, right);
- case EGREATER: return CExpr_New_EGREATER_Node(left, right);
- case ELESSEQU: return CExpr_New_ELESSEQU_Node(left, right);
- case EGREATEREQU: return CExpr_New_EGREATEREQU_Node(left, right);
- case EEQU: return CExpr_New_EEQU_Node(left, right);
- case ENOTEQU: return CExpr_New_ENOTEQU_Node(left, right);
- case ELAND: return CExpr_New_ELAND_Node(left, right);
- case ELOR: return CExpr_New_ELOR_Node(left, right);
- }
-}
-
-typedef struct DyadicInfo {
- ENodeType t;
- UInt8 prec;
-} DyadicInfo;
-
-static Boolean CExpr_GetDyadicInfo(short token, DyadicInfo *info) {
- switch (token) {
- case '*':
- info->t = EMUL;
- info->prec = 20;
- return 1;
- case '/':
- info->t = EDIV;
- info->prec = 20;
- return 1;
- case '%':
- info->t = EMODULO;
- info->prec = 20;
- return 1;
- case '+':
- info->t = EADD;
- info->prec = 19;
- return 1;
- case '-':
- info->t = ESUB;
- info->prec = 19;
- return 1;
- case TK_SHL:
- info->t = ESHL;
- info->prec = 18;
- return 1;
- case TK_SHR:
- info->t = ESHR;
- info->prec = 18;
- return 1;
- case '<':
- info->t = ELESS;
- info->prec = 17;
- return 1;
- case TK_LESS_EQUAL:
- info->t = ELESSEQU;
- info->prec = 17;
- return 1;
- case '>':
- if (disallowgreaterthan)
- return 0;
- info->t = EGREATER;
- info->prec = 17;
- return 1;
- case TK_GREATER_EQUAL:
- info->t = EGREATEREQU;
- info->prec = 17;
- return 1;
- case TK_LOGICAL_EQ:
- info->t = EEQU;
- info->prec = 16;
- return 1;
- case TK_LOGICAL_NE:
- info->t = ENOTEQU;
- info->prec = 16;
- return 1;
- case '&':
- info->t = EAND;
- info->prec = 15;
- return 1;
- case '^':
- info->t = EXOR;
- info->prec = 14;
- return 1;
- case '|':
- info->t = EOR;
- info->prec = 13;
- return 1;
- case TK_LOGICAL_AND:
- info->t = ELAND;
- info->prec = 12;
- return 1;
- case TK_LOGICAL_OR:
- info->t = ELOR;
- info->prec = 11;
- return 1;
- default:
- return 0;
- }
-}
-
-static ENode *CExpr_ParseDyadicExpression(ENode *left, UInt8 prec, Boolean no_warning) {
- ENode *right;
- Boolean is_eland_or_elor;
- Boolean save_dgt;
- Boolean cont;
- DyadicInfo left_info;
- DyadicInfo right_info;
-
- save_dgt = disallowgreaterthan;
- if (!left) {
- disallowgreaterthan = 0;
- left = pm_expression();
- disallowgreaterthan = save_dgt;
- }
-
- do {
- if (!CExpr_GetDyadicInfo(tk, &left_info))
- return left;
-
- switch (left_info.t) {
- case ELAND:
- CExpr_CheckUnwantedAssignment(left);
- if (iszero(left))
- no_warning = 1;
- is_eland_or_elor = 1;
- break;
- case ELOR:
- CExpr_CheckUnwantedAssignment(left);
- if (isnotzero(left))
- no_warning = 1;
- is_eland_or_elor = 1;
- break;
- default:
- is_eland_or_elor = 0;
- }
-
- tk = lex();
- disallowgreaterthan = 0;
- right = pm_expression();
- disallowgreaterthan = save_dgt;
- inner_loop:
- if (CExpr_GetDyadicInfo(tk, &right_info)) {
- if (left_info.prec >= right_info.prec) {
- cont = (prec >= right_info.prec);
- } else {
- right = CExpr_ParseDyadicExpression(right, left_info.prec, no_warning);
- goto inner_loop;
- }
- } else {
- cont = 1;
- }
-
- if (is_eland_or_elor)
- CExpr_CheckUnwantedAssignment(right);
-
- switch (left_info.t) {
- case EDIV:
- left = CExpr_New_EDIV_Node(left, right, no_warning);
- break;
- case EMODULO:
- left = CExpr_New_EMODULO_Node(left, right, no_warning);
- break;
- default:
- left = CExpr_NewDyadicNode(left, left_info.t, right);
- }
- } while (!cont);
-
- return left;
-}
-
-static Boolean CExpr_IsBlockMoveType(Type *type) {
- switch (type->type) {
- case TYPESTRUCT:
- case TYPECLASS:
- return 1;
- case TYPEMEMBERPOINTER:
- return type->size != 4;
- default:
- return 0;
- }
-}
-
-ENode *CExpr_New_ECOND_Node(ENode *cond, ENode *expr1, ENode *expr2) {
- ENode *result;
- ENodeList *args;
- short cost;
- Conversion conv;
-
- cond = CExpr_ConvertToCondition(pointer_generation(cond));
- expr1 = pointer_generation(expr1);
- expr2 = pointer_generation(expr2);
-
- if (!IS_TYPE_INT_OR_FLOAT(cond->rtype) && !IS_TYPE_POINTER_ONLY(cond->rtype)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- cost = cond->cost + 1;
- if (expr1->cost > expr2->cost)
- cost += expr1->cost;
- else
- cost += expr2->cost;
- if (expr2->cost > cost)
- cost = expr2->cost;
- if (cost > 200)
- cost = 200;
-
- result = CExpr_NewENode(ECOND);
- result->cost = cost;
- result->rtype = expr1->rtype;
- result->flags = expr1->flags | expr2->flags;
- result->data.cond.cond = cond;
- if (ENODE_IS(expr1, EFUNCCALL) && expr1->rtype == &stvoid && (expr1->flags & ENODE_FLAG_VOLATILE) != 0) {
- result->rtype = expr2->rtype;
- result->flags = expr2->flags;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
- if (ENODE_IS(expr2, EFUNCCALL) && expr2->rtype == &stvoid && (expr2->flags & ENODE_FLAG_VOLATILE) != 0) {
- result->rtype = expr1->rtype;
- result->flags = expr1->flags;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
-
- if (
- ENODE_IS(expr1, EINDIRECT) &&
- ENODE_IS(expr2, EINDIRECT) &&
- is_typesame(expr1->rtype, expr2->rtype) &&
- ENODE_QUALS(expr1) == ENODE_QUALS(expr2) &&
- CExpr_IsBlockMoveType(expr1->rtype) &&
- !ENODE_IS(expr1->data.monadic, EBITFIELD) &&
- !ENODE_IS(expr2->data.monadic, EBITFIELD)
- ) {
- if (isnotzero(cond))
- return expr1;
- if (iszero(cond))
- return expr2;
- result->data.cond.expr1 = getnodeaddress(expr1, 0);
- result->data.cond.expr2 = getnodeaddress(expr2, 0);
- result->rtype = result->data.cond.expr1->rtype;
- result = makemonadicnode(result, EINDIRECT);
- result->rtype = TPTR_TARGET(result->rtype);
- return result;
- }
-
- if ((IS_TYPE_CLASS(expr1->rtype) || IS_TYPE_CLASS(expr2->rtype)) && !is_typesame(expr1->rtype, expr2->rtype)) {
- if (!copts.old_argmatch) {
- if (CExpr_CondOperatorMatch(expr1, expr2, &conv)) {
- CError_ASSERT(6246, !conv.x0);
- expr1 = conv.left;
- expr2 = conv.right;
- } else if (CExpr_CanImplicitlyConvert(expr1, expr2->rtype, ENODE_QUALS(expr2))) {
- if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1)))
- CError_Error(CErrorStr188);
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1))) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else {
- goto failed;
- }
-
- result->rtype = expr1->rtype;
- } else {
- args = lalloc(sizeof(ENodeList));
- args->node = expr1;
- args->next = lalloc(sizeof(ENodeList));
- args->next->node = expr2;
- args->next->next = NULL;
-
- if (CExpr_CheckOperatorConversion(':', expr1, expr2, args, &conv)) {
- CError_ASSERT(6274, !conv.x0);
- expr1 = conv.left;
- expr2 = conv.right;
- }
-
- result->rtype = expr1->rtype;
- }
- }
-
- switch (expr1->rtype->type) {
- case TYPEENUM:
- if (expr1->rtype == expr2->rtype)
- break;
- expr1 = forceintegral(expr1);
- case TYPEINT:
- if (IS_TYPE_POINTER_ONLY(expr2->rtype) || IS_TYPE_MEMBERPOINTER(expr2->rtype)) {
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- result->rtype = expr2->rtype;
- break;
- }
- case TYPEFLOAT:
- if (expr1->rtype != expr2->rtype) {
- CExpr_ArithmeticConversion(&expr1, &expr2);
- result->rtype = expr1->rtype;
- }
- break;
- case TYPEPOINTER:
- if (ENODE_IS(expr2, EINTCONST) && CInt64_IsZero(&expr2->data.intval)) {
- expr2->rtype = TYPE(&stunsignedlong);
- break;
- }
- if (IS_TYPE_POINTER_ONLY(expr2->rtype)) {
- if (IS_TYPE_CLASS(TPTR_TARGET(expr1->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(expr2->rtype))) {
- if (TPTR_TARGET(expr1->rtype) != TPTR_TARGET(expr2->rtype)) {
- if (CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr1->rtype)), TYPE_CLASS(TPTR_TARGET(expr2->rtype)), NULL, 0, 1)) {
- expr1 = CExpr_SafeClassPointerCast(
- expr1,
- TYPE_CLASS(TPTR_TARGET(expr1->rtype)),
- TYPE_CLASS(TPTR_TARGET(expr2->rtype)),
- 0, 1);
- expr1->rtype = expr2->rtype;
- } else if (CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr2->rtype)), TYPE_CLASS(TPTR_TARGET(expr1->rtype)), NULL, 0, 1)) {
- expr2 = CExpr_SafeClassPointerCast(
- expr2,
- TYPE_CLASS(TPTR_TARGET(expr2->rtype)),
- TYPE_CLASS(TPTR_TARGET(expr1->rtype)),
- 0, 1);
- expr2->rtype = expr1->rtype;
- } else {
- goto failed;
- }
- }
- result->rtype = expr1->rtype;
- break;
- }
- if (TPTR_TARGET(expr2->rtype) == &stvoid)
- result->rtype = expr2->rtype;
- }
- if (!is_typeequal(expr1->rtype, expr2->rtype)) {
- if (!copts.objective_c)
- goto failed;
- if (!CObjC_IsCompatibleType(expr1->rtype, expr2->rtype))
- goto failed;
- expr1->rtype = expr2->rtype = CObjC_GetObjCType_id(1);
- }
- break;
- case TYPEVOID:
- if (!is_typeequal(expr1->rtype, expr2->rtype))
- goto failed;
- break;
- case TYPESTRUCT:
- case TYPECLASS:
- if (!is_typeequal(expr1->rtype, expr2->rtype))
- goto failed;
- result->rtype = expr1->rtype;
- break;
- case TYPEMEMBERPOINTER:
- if (IS_TYPE_MEMBERPOINTER(expr2->rtype) && TYPE_MEMBER_POINTER(expr1->rtype)->ty2 == TYPE_MEMBER_POINTER(expr2->rtype)->ty2) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr1, expr2->rtype, ENODE_QUALS(expr2))) {
- if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1)))
- CError_Error(CErrorStr188);
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1))) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else {
- goto failed;
- }
- result->rtype = expr1->rtype;
- break;
- default:
- failed:
- CError_Error(CErrorStr245, expr1->rtype, ENODE_QUALS(expr1), expr2->rtype, ENODE_QUALS(expr2));
- return nullnode();
- }
-
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- if (isnotzero(cond))
- result = expr1;
- else if (iszero(cond))
- result = expr2;
- return result;
-}
-
-static ENode *conditional_expression(void) {
- ENode *cond;
- ENode *expr1;
- ENode *expr2;
- ENode *result;
- Boolean is_templdep_cond;
-
- is_templdep_cond = 0;
- cond = CExpr_ParseDyadicExpression(NULL, 0, 0);
- if (tk != '?')
- return cond;
-
- cond = pointer_generation(cond);
- if (!IS_TYPE_TEMPLDEPEXPR(cond->rtype)) {
- cond = CExpr_ConvertToCondition(cond);
- if (!IS_TYPE_INT_OR_FLOAT(cond->rtype) && !IS_TYPE_POINTER_ONLY(cond->rtype)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else {
- is_templdep_cond = 1;
- }
-
- tk = lex();
- expr1 = expression();
- if (tk != ':')
- CError_ErrorSkip(CErrorStr141);
- else
- tk = lex();
-
- expr2 = (copts.cplusplus && !copts.ARMconform) ? assignment_expression() : conditional_expression();
-
- if (is_templdep_cond || IS_TYPE_TEMPLDEPEXPR(expr1->rtype) || IS_TYPE_TEMPLDEPEXPR(expr2->rtype)) {
- result = CExpr_NewENode(ECOND);
- result->rtype = &sttemplexpr;
- result->data.cond.cond = cond;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
-
- return CExpr_New_ECOND_Node(cond, expr1, expr2);
-}
-
-static ENode *CExpr_MakeOpAssNode(ENode *left, ENode *right, ENodeType nt) {
- if (left->rtype != right->rtype) {
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- right->rtype = TYPE_ENUM(right->rtype)->enumtype;
- break;
- default:
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- }
- if (IS_TYPE_FLOAT(left->rtype)) {
- if (IS_TYPE_INT(right->rtype) || (IS_TYPE_FLOAT(right->rtype) && left->rtype->size >= right->rtype->size))
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- } else if (IS_TYPE_INT(left->rtype)) {
- if (IS_TYPE_INT(right->rtype) && (left->rtype->size > right->rtype->size || (left->rtype->size == right->rtype->size && is_unsigned(left->rtype) == is_unsigned(right->rtype))))
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- }
- }
-
- return makediadicnode(left, right, nt);
-}
-
-static ENode *makeassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- ENode *tmp;
- ENode *funcexpr;
- ENodeList *args;
- Conversion conv;
-
- tk = lex();
- right = assignment_expression();
- if (copts.cplusplus) {
- if (copts.old_argmatch && !ENODE_IS(right, EMEMBER))
- right = pointer_generation(right);
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- if (!conv.x0) {
- if (nt == EASS)
- goto continue_anyway;
- CError_FATAL(6531);
- }
- return conv.x0;
- }
- if (IS_TYPE_CLASS(left->rtype) && CClass_AssignmentOperator(TYPE_CLASS(left->rtype)))
- CError_Error(CErrorStr144);
- }
-continue_anyway:
- if (IS_TYPE_ARRAY(left->rtype)) {
- if (copts.gcc_extensions && nt == EASS && is_typesame(left->rtype, right->rtype)) {
- tmp = makediadicnode(left, right, nt);
- tmp->flags = left->flags;
- return tmp;
- }
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- left = CExpr_LValue(pointer_generation(left), 1, 1);
- if (nt != EASS) {
- if (!IS_TYPE_INT(right->rtype)) {
- if (!IS_TYPE_ENUM(right->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- right = forceintegral(right);
- }
- if (!IS_TYPE_INT(left->rtype)) {
- if (copts.cplusplus) {
- CError_Error(CErrorStr144);
- return left;
- }
- left = forceintegral(left);
- if (!IS_TYPE_INT(left->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- }
- return CExpr_MakeOpAssNode(left, right, nt);
- }
-
- if (IS_TYPE_CLASS(left->rtype) && TYPE_CLASS(left->rtype)->sominfo) {
- CError_Error(CErrorStr285);
- return left;
- }
-
- if (copts.warn_implicitconv && ENODE_IS(left, EINDIRECT) && ENODE_IS(left->data.monadic, EBITFIELD) && !ENODE_IS(right, EINTCONST)) {
- copts.warn_implicitconv = 0;
- right = CExpr_AssignmentPromotion(right, left->rtype, left->flags, 1);
- copts.warn_implicitconv = 1;
- } else {
- right = CExpr_AssignmentPromotion(right, left->rtype, left->flags, 1);
- }
-
- tmp = right;
- if (IS_TYPE_FLOAT(right->rtype) && ENODE_IS(right, ETYPCON) && right->rtype->size == right->data.monadic->rtype->size)
- tmp = right->data.monadic;
-
- if (
- ENODE_IS(left, EINDIRECT) &&
- ENODE_IS(left->data.monadic, EOBJREF) &&
- ENODE_IS(tmp, EINDIRECT) &&
- (ENODE_IS(funcexpr = right->data.monadic, EFUNCCALL) || ENODE_IS(funcexpr, EFUNCCALLP)) &&
- left->rtype == funcexpr->data.funccall.functype->functype &&
- CMach_GetFunctionResultClass(funcexpr->data.funccall.functype) == 1 &&
- (args = funcexpr->data.funccall.args)
- ) {
- switch (CABI_GetStructResultArgumentIndex(funcexpr->data.funccall.functype)) {
- case 0:
- break;
- case 1:
- if ((args = args->next))
- break;
- CError_FATAL(6625);
- default:
- CError_FATAL(6626);
- }
- if (ENODE_IS(args->node, ETEMP)) {
- if (!(IS_TYPE_CLASS(left->rtype) && CClass_Destructor(TYPE_CLASS(left->rtype)))) {
- args->node = getnodeaddress(left, 0);
- return right;
- }
- }
- }
-
- right = makediadicnode(left, right, nt);
- right->flags = left->flags;
- return right;
-}
-
-static ENode *makepassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- Boolean is_array;
- Conversion conv;
-
- is_array = IS_TYPE_ARRAY(left->rtype);
- left = pointer_generation(left);
- if (copts.cplusplus) {
- tk = lex();
- right = pointer_generation(assignment_expression());
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- CError_ASSERT(6669, conv.x0);
- return conv.x0;
- }
- left = CExpr_LValue(left, 1, 1);
- } else {
- left = CExpr_LValue(left, 1, 1);
- tk = lex();
- right = pointer_generation(assignment_expression());
- }
-
- if (is_array)
- CError_Error(CErrorStr144);
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- break;
- case TYPEENUM:
- if (copts.cplusplus) {
- CError_Error(CErrorStr144);
- return left;
- }
- left = forceintegral(left);
- break;
- default:
- CError_Error(CErrorStr144);
- return left;
- }
-
- if (IS_TYPE_ENUM(right->rtype))
- right = forceintegral(right);
-
- if (iszero(right))
- return left;
-
- if (IS_TYPE_POINTER_ONLY(left->rtype)) {
- if (IS_TYPE_INT(right->rtype)) {
- if (nt == ESUBASS) {
- left = psub(left, right);
- if (ENODE_IS(left, ESUB))
- left->type = ESUBASS;
- return left;
- } else {
- left = padd(left, right);
- if (ENODE_IS(left, EADD))
- left->type = EADDASS;
- return left;
- }
- }
- CError_Error(CErrorStr144);
- return left;
- } else {
- return CExpr_MakeOpAssNode(left, right, nt);
- }
-}
-
-static ENode *makemulassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- Boolean is_array;
- Conversion conv;
-
- is_array = IS_TYPE_ARRAY(left->rtype);
- left = pointer_generation(left);
- if (copts.cplusplus) {
- tk = lex();
- right = pointer_generation(assignment_expression());
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- CError_ASSERT(6753, conv.x0);
- return conv.x0;
- }
- if (!IS_TYPE_INT(left->rtype) && !(IS_TYPE_FLOAT(left->rtype) && nt != EMODASS)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- left = CExpr_LValue(left, 1, 1);
- } else {
- if (IS_TYPE_ENUM(left->rtype))
- left = forceintegral(left);
- if (!IS_TYPE_INT(left->rtype) && !(IS_TYPE_FLOAT(left->rtype) && nt != EMODASS)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- left = CExpr_LValue(left, 1, 1);
- tk = lex();
- right = pointer_generation(assignment_expression());
- }
-
- if (is_array)
- CError_Error(CErrorStr144);
-
- if (IS_TYPE_ENUM(right->rtype))
- right = forceintegral(right);
-
- if (IS_TYPE_INT(left->rtype) && IS_TYPE_FLOAT(right->rtype) && nt == EMODASS) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- return CExpr_MakeOpAssNode(left, right, nt);
-}
-
-static ENode *CExpr_TransformOpAssign(ENode *expr) {
- switch (expr->type) {
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- if (expr->rtype == TYPE(&stbool)) {
- expr = CIRTrans_TransformOpAss(expr);
- if (ENODE_IS(expr, EASS)) {
- expr->data.diadic.right = makemonadicnode(expr->data.diadic.right, ELOGNOT);
- expr->data.diadic.right->rtype = TYPE(&stbool);
- expr->data.diadic.right = makemonadicnode(expr->data.diadic.right, ELOGNOT);
- }
- }
- }
-
- return expr;
-}
-
-ENode *assignment_expression(void) {
- ENode *expr;
-
- if (tk == TK_THROW)
- return CExcept_ScanThrowExpression();
-
- expr = conditional_expression();
- switch (tk) {
- case '=':
- return makeassignmentnode(expr, EASS, tk);
- case TK_ADD_ASSIGN:
- return CExpr_TransformOpAssign(makepassignmentnode(expr, EADDASS, tk));
- case TK_SUB_ASSIGN:
- return CExpr_TransformOpAssign(makepassignmentnode(expr, ESUBASS, tk));
- case TK_MULT_ASSIGN:
- expr = makemulassignmentnode(expr, EMULASS, tk);
- if (ENODE_IS(expr, EMULASS) && CExpr_IsOne(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_DIV_ASSIGN:
- expr = makemulassignmentnode(expr, EDIVASS, tk);
- if (ENODE_IS(expr, EDIVASS)) {
- if (iszero(expr->data.diadic.right) && !IS_TYPE_FLOAT(expr->rtype)) {
- CError_Warning(CErrorStr139);
- return expr->data.diadic.left;
- }
- if (CExpr_IsOne(expr->data.diadic.right))
- return expr->data.diadic.left;
- }
- return CExpr_TransformOpAssign(expr);
- case TK_MOD_ASSIGN:
- expr = makemulassignmentnode(expr, EMODASS, tk);
- if (ENODE_IS(expr, EMODASS)) {
- if (iszero(expr->data.diadic.right)) {
- CError_Warning(CErrorStr139);
- return expr->data.diadic.left;
- }
- }
- return CExpr_TransformOpAssign(expr);
- case TK_SHL_ASSIGN:
- expr = makeassignmentnode(expr, ESHLASS, tk);
- if (ENODE_IS(expr, ESHLASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_SHR_ASSIGN:
- expr = makeassignmentnode(expr, ESHRASS, tk);
- if (ENODE_IS(expr, ESHRASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_AND_ASSIGN:
- expr = makeassignmentnode(expr, EANDASS, tk);
- if (ENODE_IS(expr, EANDASS) && CExpr_AllBitsSet(expr->data.diadic.right))
- return expr->data.diadic.left;
- return expr;
- case TK_XOR_ASSIGN:
- expr = makeassignmentnode(expr, EXORASS, tk);
- if (ENODE_IS(expr, EXORASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_OR_ASSIGN:
- expr = makeassignmentnode(expr, EORASS, tk);
- if (ENODE_IS(expr, EORASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- default:
- return expr;
- }
-}
-
-ENode *conv_assignment_expression(void) {
- return pointer_generation(assignment_expression());
-}
-
-static Boolean CExpr_HasSideEffect(ENode *expr) {
- switch (expr->type) {
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EROTL:
- case EROTR:
- case EBITFIELD:
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case ETEMP:
- case EARGOBJ:
- case ELOCOBJ:
- case EOBJLIST:
- case EMEMBER:
- case EVECTOR128CONST:
- return 0;
- case ETYPCON:
- return IS_TYPE_VOID(expr->rtype);
- case EINDIRECT:
- switch (expr->data.monadic->type) {
- case EFUNCCALL:
- case EFUNCCALLP:
- return 1;
- default:
- return 0;
- }
- case ECOMMA:
- return CInline_ExpressionHasSideEffect(expr->data.diadic.right);
- case ECOND:
- return CInline_ExpressionHasSideEffect(expr->data.cond.expr1) || CInline_ExpressionHasSideEffect(expr->data.cond.expr2);
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EFORCELOAD:
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EFUNCCALL:
- case EFUNCCALLP:
- case EMFPOINTER:
- case ENULLCHECK:
- case EPRECOMP:
- case ELABEL:
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- case EINITTRYCATCH:
- case EINSTRUCTION:
- return 1;
- default:
- CError_FATAL(7056);
- return 0;
- }
-}
-
-void CExpr_CheckUnusedExpression(ENode *expr) {
- ENode *scan;
- ENodeList *arg;
-
- if (copts.warn_possunwant) {
- scan = expr;
- while (ENODE_IS(scan, ETYPCON))
- scan = scan->data.monadic;
- if (ENODE_IS(scan, EEQU)) {
- CError_Warning(CErrorStr208);
- return;
- }
- }
-
- if (copts.warn_no_side_effect) {
- if (!CExpr_HasSideEffect(expr)) {
- CError_Warning(CErrorStr369);
- return;
- }
- }
-
- if (copts.warn_resultnotused) {
- scan = expr;
- if (IS_TYPE_VOID(expr->rtype))
- return;
- if (ENODE_IS(expr, EINDIRECT))
- scan = expr->data.monadic;
-
- switch (scan->type) {
- case EFUNCCALL:
- case EFUNCCALLP:
- if (ENODE_IS(scan->data.funccall.funcref, EOBJREF) && scan->data.funccall.funcref->data.objref->name == asop_name_node)
- return;
- if (CMach_GetFunctionResultClass(scan->data.funccall.functype) == 1 && (arg = scan->data.funccall.args)) {
- switch (CABI_GetStructResultArgumentIndex(scan->data.funccall.functype)) {
- case 0:
- break;
- case 1:
- if ((arg = arg->next))
- break;
- CError_FATAL(7110);
- default:
- CError_FATAL(7111);
- }
-
- if (!ENODE_IS(arg->node, ETEMP))
- return;
- }
- CError_Warning(CErrorStr370);
- }
- }
-}
-
-ENode *s_expression(void) {
- ENode *left;
- ENode *right;
- Conversion conv;
-
- left = assignment_expression();
- while (tk == ',') {
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(assignment_expression());
-
- if (copts.cplusplus && CExpr_CheckOperator(',', left, right, &conv)) {
- CError_ASSERT(7143, left = conv.x0);
- } else {
- CExpr_CheckUnusedExpression(left);
- left = makecommaexpression(left, right);
- left->rtype = right->rtype;
- }
- }
-
- return left;
-}
-
-ENode *expression(void) {
- return pointer_generation(s_expression());
-}
-
-CInt64 CExpr_IntegralConstExprType(Type **tint) {
- ENode *expr;
-
- expr = pointer_generation(conditional_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- *tint = expr->rtype;
- return expr->data.intval;
- case TYPEENUM:
- *tint = TYPE_ENUM(expr->rtype)->enumtype;
- return expr->data.intval;
- }
- }
-
- CError_Error(CErrorStr124);
- *tint = TYPE(&stchar);
- return cint64_zero;
-}
-
-ENode *CExpr_IntegralConstOrDepExpr(void) {
- ENode *expr;
-
- expr = pointer_generation(conditional_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- return expr;
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- return expr;
- default:
- CError_FATAL(7209);
- }
- }
-
- if (CTemplTool_IsTemplateArgumentDependentExpression(expr))
- return expr;
-
- CError_Error(CErrorStr124);
- expr = nullnode();
- expr->rtype = TYPE(&stchar);
- return expr;
-}
-
-CInt64 CExpr_IntegralConstExpr(void) {
- Type *throwaway;
- return CExpr_IntegralConstExprType(&throwaway);
-}
-
-void CExpr_CheckUnwantedAssignment(ENode *expr) {
- if (copts.warn_possunwant) {
- if (ENODE_IS(expr, EASS) && !(expr->flags & ENODE_FLAG_80))
- CError_Warning(CErrorStr207);
- }
-}
-
-Boolean CExpr_ParseAsmExpr(Object **objptr, CInt64 *valptr) {
- ENode *expr;
-
- if (objptr)
- *objptr = NULL;
- *valptr = cint64_zero;
-
- expr = pointer_generation(assignment_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- *valptr = expr->data.intval;
- return 1;
- }
-
- if (objptr) {
- switch (expr->type) {
- case EINDIRECT:
- if (CInit_RelocInitCheck(expr->data.monadic, objptr, valptr, 1))
- return 1;
- break;
- case EOBJREF:
- *objptr = expr->data.objref;
- while ((*objptr)->datatype == DALIAS)
- *objptr = (*objptr)->u.alias.object;
- return 1;
- case EMEMBER:
- if (expr->data.emember->list->object->otype == OT_OBJECT) {
- if (expr->data.emember->list->next && expr->data.emember->list->next->object->otype == OT_OBJECT)
- CError_Error(CErrorStr199);
- *objptr = OBJECT(expr->data.emember->list->object);
- while ((*objptr)->datatype == DALIAS)
- *objptr = (*objptr)->u.alias.object;
- return 1;
- }
- break;
- case EOBJLIST:
- CError_Error(CErrorStr199);
- return 0;
- }
- }
-
- CError_Error(CErrorStr155);
- return 0;
-}