X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fexpr.c;h=276215f7418617bcd7a9695cbf99f5d19121d30f;hb=84f85293f1662f30b44f5caf1fae2b5d5b8be0f7;hp=11c43b9730a2f0095febc67d4a02de3282305243;hpb=59bcc726b6ecf668aa1b8805cba84ec880bbf61e;p=cc65 diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 11c43b973..276215f74 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -226,7 +226,7 @@ unsigned assignadjust (type* lhst, struct expent* rhs) * as const. */ unsigned flags = TypeOf (rhst); - if (rhs->e_flags & E_MCONST) { + if (rhs->e_flags == E_MCONST) { flags |= CF_CONST; } return g_typeadjust (TypeOf (lhst) | CF_CONST, flags); @@ -257,7 +257,7 @@ unsigned assignadjust (type* lhst, struct expent* rhs) } } else if (IsClassInt (rhst)) { /* Int to pointer assignment is valid only for constant zero */ - if ((rhs->e_flags & E_MCONST) == 0 || rhs->e_const != 0) { + if (rhs->e_flags != E_MCONST || rhs->e_const != 0) { Warning ("Converting integer to pointer without a cast"); } } else if (IsTypeFuncPtr (lhst) && IsTypeFunc(rhst)) { @@ -309,7 +309,7 @@ void DefineData (struct expent* lval) case E_TLIT: /* a literal of some kind */ - g_defdata (CF_STATIC, LiteralLabel, lval->e_const); + g_defdata (CF_STATIC, LiteralPoolLabel, lval->e_const); break; default: @@ -352,7 +352,7 @@ static void lconst (unsigned flags, struct expent* lval) case E_TLIT: /* Literal string */ - g_getimmed (CF_STATIC, LiteralLabel, lval->e_const); + g_getimmed (CF_STATIC, LiteralPoolLabel, lval->e_const); break; default: @@ -431,13 +431,12 @@ static int istypeexpr (void) { SymEntry* Entry; - return curtok == TOK_LPAREN && ( - (nxttok >= TOK_FIRSTTYPE && nxttok <= TOK_LASTTYPE) || - (nxttok == TOK_CONST) || - (nxttok == TOK_IDENT && - (Entry = FindSym (NextTok.Ident)) != 0 && - IsTypeDef (Entry)) - ); + return CurTok.Tok == TOK_LPAREN && ( + (NextTok.Tok >= TOK_FIRSTTYPE && NextTok.Tok <= TOK_LASTTYPE) || + (NextTok.Tok == TOK_CONST) || + (NextTok.Tok == TOK_IDENT && + (Entry = FindSym (NextTok.Ident)) != 0 && + IsTypeDef (Entry))); } @@ -502,7 +501,6 @@ void exprhs (unsigned flags, int k, struct expent *lval) } if (lval->e_test & E_FORCETEST) { /* we testing this value? */ /* debug... */ - AddCodeHint ("forcetest"); flags |= TypeOf (lval->e_tptr); g_test (flags); /* yes, force a test */ lval->e_test &= ~E_FORCETEST; @@ -510,54 +508,67 @@ void exprhs (unsigned flags, int k, struct expent *lval) } -static void callfunction (struct expent* lval) -/* Perform a function call. Called from hie11, this routine will - * either call the named function, or if the supplied ptr is zero, - * will call the contents of P. + +static unsigned FunctionParamList (FuncDesc* Func) +/* Parse a function parameter list and pass the parameters to the called + * function. Depending on several criteria this may be done by just pushing + * each parameter separately, or creating the parameter frame once and then + * storing into this frame. + * The function returns the size of the parameters pushed. */ { - struct expent lval2; - FuncDesc* Func; /* Function descriptor */ - int Ellipsis; /* True if we have an open param list */ - SymEntry* Param; /* Current formal parameter */ - unsigned ParamCount; /* Actual parameter count */ - unsigned ParamSize; /* Number of parameter bytes */ - unsigned Flags; - unsigned CFlags; - CodeMark Mark; - - - /* Get a pointer to the function descriptor from the type string */ - Func = GetFuncDesc (lval->e_tptr); - - /* Initialize vars to keep gcc silent */ - Param = 0; - Mark = 0; + struct expent lval; - /* Check if this is a function pointer. If so, save it. If not, check for - * special known library functions that may be inlined. + /* Initialize variables */ + SymEntry* Param = 0; /* Keep gcc silent */ + unsigned ParamSize = 0; /* Size of parameters pushed */ + unsigned ParamCount = 0; /* Number of parameters pushed */ + unsigned FrameSize = 0; /* Size of parameter frame */ + unsigned FrameParams = 0; /* Number of params in frame */ + int FrameOffs = 0; /* Offset into parameter frame */ + int Ellipsis = 0; /* Function is variadic */ + + /* As an optimization, we may allocate the complete parameter frame at + * once instead of pushing each parameter as it comes. We may do that, + * if... + * + * - optimizations that increase code size are enabled (allocating the + * stack frame at once gives usually larger code). + * - we have more than one parameter to push (don't count the last param + * for __fastcall__ functions). */ - if (lval->e_flags & E_MEXPR) { - /* Function pointer is in primary register, save it */ - Mark = GetCodePos (); - g_save (CF_PTR); - } else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) { - /* Inline this function */ - HandleStdFunc (lval); - return; + if (CodeSizeFactor >= 200) { + + /* Calculate the number and size of the parameters */ + FrameParams = Func->ParamCount; + FrameSize = Func->ParamSize; + if (FrameParams > 0 && (Func->Flags & FD_FASTCALL) != 0) { + /* Last parameter is not pushed */ + const SymEntry* LastParam = Func->SymTab->SymTail; + FrameSize -= SizeOf (LastParam->Type); + --FrameParams; + } + + /* Do we have more than one parameter in the frame? */ + if (FrameParams > 1) { + /* Okeydokey, setup the frame */ + FrameOffs = oursp; + g_space (FrameSize); + oursp -= FrameSize; + } else { + /* Don't use a preallocated frame */ + FrameSize = 0; + } } /* Parse the actual parameter list */ - ParamSize = 0; - ParamCount = 0; - Ellipsis = 0; - while (curtok != TOK_RPAREN) { + while (CurTok.Tok != TOK_RPAREN) { - /* Add a hint for the optimizer */ - AddCodeHint ("param:start"); + unsigned CFlags; + unsigned Flags; - /* Count arguments */ - ++ParamCount; + /* Count arguments */ + ++ParamCount; /* Fetch the pointer to the next argument, check for too many args */ if (ParamCount <= Func->ParamCount) { @@ -579,7 +590,7 @@ static void callfunction (struct expent* lval) } } else if (!Ellipsis) { /* Too many arguments. Do we have an open param list? */ - if ((Func->Flags & FD_ELLIPSIS) == 0) { + if ((Func->Flags & FD_VARIADIC) == 0) { /* End of param list reached, no ellipsis */ Error ("Too many arguments in function call"); } @@ -596,8 +607,8 @@ static void callfunction (struct expent* lval) if (!Ellipsis && SizeOf (Param->Type) == 1) { CFlags = CF_FORCECHAR; } - Flags = 0; - if (evalexpr (CFlags, hie1, &lval2) == 0) { + Flags = CF_NONE; + if (evalexpr (CFlags, hie1, &lval) == 0) { /* A constant value */ Flags |= CF_CONST; } @@ -607,14 +618,14 @@ static void callfunction (struct expent* lval) */ if (!Ellipsis) { /* Promote the argument if needed */ - assignadjust (Param->Type, &lval2); + assignadjust (Param->Type, &lval); /* If we have a prototype, chars may be pushed as chars */ Flags |= CF_FORCECHAR; } /* Use the type of the argument for the push */ - Flags |= TypeOf (lval2.e_tptr); + Flags |= TypeOf (lval.e_tptr); /* If this is a fastcall function, don't push the last argument */ if (ParamCount == Func->ParamCount && (Func->Flags & FD_FASTCALL) != 0) { @@ -623,32 +634,86 @@ static void callfunction (struct expent* lval) * the primary. */ if (Flags & CF_CONST) { - exprhs (CF_FORCECHAR, 0, &lval2); + exprhs (CF_FORCECHAR, 0, &lval); } } else { - /* Push the argument, count the argument size */ - g_push (Flags, lval2.e_const); - ParamSize += sizeofarg (Flags); - } + unsigned ArgSize = sizeofarg (Flags); + if (FrameSize > 0) { + /* We have the space already allocated, store in the frame */ + CHECK (FrameSize >= ArgSize); + FrameSize -= ArgSize; + FrameOffs -= ArgSize; + /* Store */ + g_putlocal (Flags | CF_NOKEEP, FrameOffs, lval.e_const); + } else { + /* Push the argument */ + g_push (Flags, lval.e_const); + } - /* Add an optimizer hint */ - AddCodeHint ("param:end"); + /* Calculate total parameter size */ + ParamSize += ArgSize; + } /* Check for end of argument list */ - if (curtok != TOK_COMMA) { + if (CurTok.Tok != TOK_COMMA) { break; } NextToken (); } - /* We need the closing bracket here */ - ConsumeRParen (); - /* Check if we had enough parameters */ if (ParamCount < Func->ParamCount) { Error ("Too few arguments in function call"); } + /* The function returns the size of all parameters pushed onto the stack. + * However, if there are parameters missing (which is an error and was + * flagged by the compiler) AND a stack frame was preallocated above, + * we would loose track of the stackpointer and generate an internal error + * later. So we correct the value by the parameters that should have been + * pushed to avoid an internal compiler error. Since an error was + * generated before, no code will be output anyway. + */ + return ParamSize + FrameSize; +} + + + +static void CallFunction (struct expent* lval) +/* Perform a function call. Called from hie11, this routine will + * either call the named function, or the function pointer in a/x. + */ +{ + FuncDesc* Func; /* Function descriptor */ + unsigned ParamSize; /* Number of parameter bytes */ + CodeMark Mark; + + + /* Get a pointer to the function descriptor from the type string */ + Func = GetFuncDesc (lval->e_tptr); + + /* Initialize vars to keep gcc silent */ + Mark = 0; + + /* Check if this is a function pointer. If so, save it. If not, check for + * special known library functions that may be inlined. + */ + if (lval->e_flags & E_MEXPR) { + /* Function pointer is in primary register, save it */ + Mark = GetCodePos (); + g_save (CF_PTR); + } else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) { + /* Inline this function */ + HandleStdFunc (lval); + return; + } + + /* Parse the parameter list */ + ParamSize = FunctionParamList (Func); + + /* We need the closing bracket here */ + ConsumeRParen (); + /* */ if (lval->e_flags & E_MEXPR) { /* Function called via pointer: Restore it and call function */ @@ -660,7 +725,7 @@ static void callfunction (struct expent* lval) } g_callind (TypeOf (lval->e_tptr), ParamSize); } else { - g_call (TypeOf (lval->e_tptr), (char*) lval->e_name, ParamSize); + g_call (TypeOf (lval->e_tptr), (const char*) lval->e_name, ParamSize); } } @@ -679,18 +744,35 @@ void doasm (void) ConsumeLParen (); /* String literal */ - if (curtok != TOK_SCONST) { + if (CurTok.Tok != TOK_SCONST) { Error ("String literal expected"); } else { - /* Write the string directly into the output, followed by a newline */ - AddCodeLine (GetLiteral (curval)); + + /* The string literal may consist of more than one line of assembler + * code. Separate the single lines and output the code. + */ + const char* S = GetLiteral (CurTok.IVal); + while (*S) { + + /* Allow lines up to 256 bytes */ + const char* E = strchr (S, '\n'); + if (E) { + /* Found a newline */ + g_asmcode (S, E-S); + S = E+1; + } else { + int Len = strlen (S); + g_asmcode (S, Len); + S += Len; + } + } /* Reset the string pointer, effectivly clearing the string from the * string table. Since we're working with one token lookahead, this * will fail if the next token is also a string token, but that's a * syntax error anyway, because we expect a right paren. */ - ResetLiteralOffs (curval); + ResetLiteralPoolOffs (CurTok.IVal); } /* Skip the string token */ @@ -711,10 +793,10 @@ static int primary (struct expent* lval) lval->e_test = 0; /* Character and integer constants. */ - if (curtok == TOK_ICONST || curtok == TOK_CCONST) { + if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) { lval->e_flags = E_MCONST | E_TCONST; - lval->e_tptr = curtype; - lval->e_const = curval; + lval->e_tptr = CurTok.Type; + lval->e_const = CurTok.IVal; NextToken (); return 0; } @@ -722,7 +804,7 @@ static int primary (struct expent* lval) /* Process parenthesized subexpression by calling the whole parser * recursively. */ - if (curtok == TOK_LPAREN) { + if (CurTok.Tok == TOK_LPAREN) { NextToken (); memset (lval, 0, sizeof (*lval)); /* Remove any attributes */ k = hie0 (lval); @@ -742,7 +824,7 @@ static int primary (struct expent* lval) } /* Identifier? */ - if (curtok == TOK_IDENT) { + if (CurTok.Tok == TOK_IDENT) { SymEntry* Sym; ident Ident; @@ -832,7 +914,7 @@ static int primary (struct expent* lval) NextToken (); /* IDENT is either an auto-declared function or an undefined variable. */ - if (curtok == TOK_LPAREN) { + if (CurTok.Tok == TOK_LPAREN) { /* Declare a function returning int. For that purpose, prepare a * function signature for a function having an empty param list * and returning int. @@ -859,16 +941,16 @@ static int primary (struct expent* lval) } /* String literal? */ - if (curtok == TOK_SCONST) { + if (CurTok.Tok == TOK_SCONST) { lval->e_flags = E_MCONST | E_TLIT; - lval->e_const = curval; - lval->e_tptr = GetCharArrayType (strlen (GetLiteral (curval))); + lval->e_const = CurTok.IVal; + lval->e_tptr = GetCharArrayType (strlen (GetLiteral (CurTok.IVal))); NextToken (); return 0; } /* ASM statement? */ - if (curtok == TOK_ASM) { + if (CurTok.Tok == TOK_ASM) { doasm (); lval->e_tptr = type_void; lval->e_flags = E_MEXPR; @@ -877,8 +959,8 @@ static int primary (struct expent* lval) } /* __AX__ and __EAX__ pseudo values? */ - if (curtok == TOK_AX || curtok == TOK_EAX) { - lval->e_tptr = (curtok == TOK_AX)? type_uint : type_ulong; + if (CurTok.Tok == TOK_AX || CurTok.Tok == TOK_EAX) { + lval->e_tptr = (CurTok.Tok == TOK_AX)? type_uint : type_ulong; lval->e_flags = E_MREG; lval->e_test &= ~E_CC; lval->e_const = 0; @@ -1137,7 +1219,7 @@ static int structref (int k, struct expent* lval) /* Skip the token and check for an identifier */ NextToken (); - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); lval->e_tptr = type_int; return 0; @@ -1181,19 +1263,19 @@ static int hie11 (struct expent *lval) k = primary (lval); - if (curtok < TOK_LBRACK || curtok > TOK_PTR_REF) { + if (CurTok.Tok < TOK_LBRACK || CurTok.Tok > TOK_PTR_REF) { /* Not for us */ return k; } while (1) { - if (curtok == TOK_LBRACK) { + if (CurTok.Tok == TOK_LBRACK) { /* Array reference */ k = arrayref (k, lval); - } else if (curtok == TOK_LPAREN) { + } else if (CurTok.Tok == TOK_LPAREN) { /* Function call. Skip the opening parenthesis */ NextToken (); @@ -1205,7 +1287,7 @@ static int hie11 (struct expent *lval) ++lval->e_tptr; /* Skip T_PTR */ lval->e_flags |= E_MEXPR; } - callfunction (lval); + CallFunction (lval); lval->e_flags = E_MEXPR; lval->e_tptr += DECODE_SIZE + 1; /* Set to result */ } else { @@ -1213,14 +1295,14 @@ static int hie11 (struct expent *lval) } k = 0; - } else if (curtok == TOK_DOT) { + } else if (CurTok.Tok == TOK_DOT) { if (!IsClassStruct (lval->e_tptr)) { Error ("Struct expected"); } k = structref (0, lval); - } else if (curtok == TOK_PTR_REF) { + } else if (CurTok.Tok == TOK_PTR_REF) { tptr = lval->e_tptr; if (tptr[0] != T_PTR || (tptr[1] & T_STRUCT) == 0) { @@ -1255,7 +1337,7 @@ static void store (struct expent* lval) g_putstatic (flags, lval->e_name, lval->e_const); } else if (f & E_MLOCAL) { - g_putlocal (flags, lval->e_const); + g_putlocal (flags, lval->e_const, 0); } else if (f == E_MEOFFS) { g_putind (flags, lval->e_const); } else if (f != E_MREG) { @@ -1401,10 +1483,10 @@ static void unaryop (int tok, struct expent* lval) NextToken (); k = hie10 (lval); - if (k == 0 && lval->e_flags & E_MCONST) { + if (k == 0 && (lval->e_flags & E_MCONST) != 0) { /* Value is constant */ switch (tok) { - case TOK_MINUS: lval->e_const = -lval->e_const; break; + case TOK_MINUS: lval->e_const = -lval->e_const; break; case TOK_PLUS: break; case TOK_COMP: lval->e_const = ~lval->e_const; break; default: Internal ("Unexpected token: %d", tok); @@ -1529,7 +1611,7 @@ static int hie10 (struct expent* lval) int k; type* t; - switch (curtok) { + switch (CurTok.Tok) { case TOK_INC: pre_incdec (lval, g_inc); @@ -1542,7 +1624,7 @@ static int hie10 (struct expent* lval) case TOK_PLUS: case TOK_MINUS: case TOK_COMP: - unaryop (curtok, lval); + unaryop (CurTok.Tok, lval); return 0; case TOK_BOOL_NOT: @@ -1619,7 +1701,7 @@ static int hie10 (struct expent* lval) } k = hie11 (lval); - switch (curtok) { + switch (CurTok.Tok) { case TOK_INC: post_incdec (lval, k, g_inc); return 0; @@ -1654,7 +1736,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */ k = hienext (lval); *UsedGen = 0; - while ((Gen = FindGen (curtok, ops)) != 0) { + while ((Gen = FindGen (CurTok.Tok, ops)) != 0) { /* Tell the caller that we handled it's ops */ *UsedGen = 1; @@ -1665,7 +1747,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */ } /* Remember the operator token, then skip it */ - tok = curtok; + tok = CurTok.Tok; NextToken (); /* Get the lhs on stack */ @@ -1762,10 +1844,10 @@ static int hie_compare (GenDesc** ops, /* List of generators */ k = hienext (lval); - while ((Gen = FindGen (curtok, ops)) != 0) { + while ((Gen = FindGen (CurTok.Tok, ops)) != 0) { /* Remember the operator token, then skip it */ - tok = curtok; + tok = CurTok.Tok; NextToken (); /* Get the lhs on stack */ @@ -1903,7 +1985,7 @@ static void parseadd (int k, struct expent* lval) flags = 0; /* Check for constness on both sides */ - if (k == 0 && lval->e_flags == E_MCONST) { + if (k == 0 && (lval->e_flags & E_MCONST) != 0) { /* The left hand side is a constant. Good. Get rhs */ if (evalexpr (CF_NONE, hie9, &lval2) == 0) { @@ -1931,7 +2013,7 @@ static void parseadd (int k, struct expent* lval) } /* Result is constant, condition codes not set */ - lval->e_test = E_MCONST; + lval->e_test &= ~E_CC; } else { @@ -2088,7 +2170,7 @@ static void parsesub (int k, struct expent* lval) rhst = lval2.e_tptr; /* Check left hand side */ - if (k == 0 && lval->e_flags & E_MCONST) { + if (k == 0 && (lval->e_flags & E_MCONST) != 0) { /* Both sides are constant, remove generated code */ RemoveCode (Mark1); @@ -2118,7 +2200,7 @@ static void parsesub (int k, struct expent* lval) } /* Result is constant, condition codes not set */ - lval->e_flags = E_MCONST; + /* lval->e_flags = E_MCONST; ### */ lval->e_test &= ~E_CC; } else { @@ -2222,9 +2304,9 @@ static int hie8 (struct expent* lval) /* Process + and - binary operators. */ { int k = hie9 (lval); - while (curtok == TOK_PLUS || curtok == TOK_MINUS) { + while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) { - if (curtok == TOK_PLUS) { + if (CurTok.Tok == TOK_PLUS) { parseadd (k, lval); } else { parsesub (k, lval); @@ -2318,13 +2400,13 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) struct expent lval2; k = hie2 (lval); - if (curtok == TOK_BOOL_AND) { + if (CurTok.Tok == TOK_BOOL_AND) { /* Tell our caller that we're evaluating a boolean */ *BoolOp = 1; /* Get a label that we will use for false expressions */ - lab = GetLabel (); + lab = GetLocalLabel (); /* If the expr hasn't set condition codes, set the force-test flag */ if ((lval->e_test & E_CC) == 0) { @@ -2338,7 +2420,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) g_falsejump (CF_NONE, lab); /* Parse more boolean and's */ - while (curtok == TOK_BOOL_AND) { + while (CurTok.Tok == TOK_BOOL_AND) { /* Skip the && */ NextToken (); @@ -2351,7 +2433,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) exprhs (CF_FORCECHAR, k, &lval2); /* Do short circuit evaluation */ - if (curtok == TOK_BOOL_AND) { + if (CurTok.Tok == TOK_BOOL_AND) { g_falsejump (CF_NONE, lab); } else { /* Last expression - will evaluate to true */ @@ -2360,7 +2442,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) } /* Define the false jump label here */ - g_defloclabel (lab); + g_defcodelabel (lab); /* Define the label */ lval->e_flags = E_MEXPR; @@ -2383,13 +2465,13 @@ static int hieOr (struct expent *lval) unsigned DoneLab; /* Get a label */ - TrueLab = GetLabel (); + TrueLab = GetLocalLabel (); /* Call the next level parser */ k = hieAnd (lval, TrueLab, &BoolOp); /* Any boolean or's? */ - if (curtok == TOK_BOOL_OR) { + if (CurTok.Tok == TOK_BOOL_OR) { /* If the expr hasn't set condition codes, set the force-test flag */ if ((lval->e_test & E_CC) == 0) { @@ -2410,7 +2492,7 @@ static int hieOr (struct expent *lval) BoolOp = 1; /* while there's more expr */ - while (curtok == TOK_BOOL_OR) { + while (CurTok.Tok == TOK_BOOL_OR) { /* skip the || */ NextToken (); @@ -2429,7 +2511,7 @@ static int hieOr (struct expent *lval) */ #if 0 /* Seems this sometimes generates wrong code */ - if (curtok == TOK_BOOL_OR && !AndOp) { + if (CurTok.Tok == TOK_BOOL_OR && !AndOp) { g_truejump (CF_NONE, TrueLab); } #else @@ -2443,12 +2525,12 @@ static int hieOr (struct expent *lval) /* If we really had boolean ops, generate the end sequence */ if (BoolOp) { - DoneLab = GetLabel (); + DoneLab = GetLocalLabel (); g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); - g_defloclabel (TrueLab); + g_defcodelabel (TrueLab); g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defloclabel (DoneLab); + g_defcodelabel (DoneLab); } return k; } @@ -2472,22 +2554,22 @@ static int hieQuest (struct expent *lval) k = hieOr (lval); - if (curtok == TOK_QUEST) { + if (CurTok.Tok == TOK_QUEST) { NextToken (); if ((lval->e_test & E_CC) == 0) { /* Condition codes not set, force a test */ lval->e_test |= E_FORCETEST; } exprhs (CF_NONE, k, lval); - labf = GetLabel (); + labf = GetLocalLabel (); g_falsejump (CF_NONE, labf); /* Parse second and third expression */ expression1 (&lval2); - labt = GetLabel (); + labt = GetLocalLabel (); ConsumeColon (); g_jump (labt); - g_defloclabel (labf); + g_defcodelabel (labf); expression1 (&lval3); /* Check if any conversions are needed, if so, do them. @@ -2514,27 +2596,20 @@ static int hieQuest (struct expent *lval) /* Setup a new label so that the expr3 code will jump around * the type cast code for expr2. */ - labf = GetLabel (); /* Get new label */ + labf = GetLocalLabel (); /* Get new label */ Mark1 = GetCodePos (); /* Remember current position */ g_jump (labf); /* Jump around code */ /* The jump for expr2 goes here */ - g_defloclabel (labt); + g_defcodelabel (labt); /* Create the typecast code for expr2 */ Mark2 = GetCodePos (); /* Remember position */ g_typecast (TypeOf (rtype), TypeOf (type2)); - /* If the typecast did not produce code, remove the jump, - * otherwise output the label. - */ - if (GetCodePos() == Mark2) { - RemoveCode (Mark1); /* Remove code */ - } else { - /* We have typecast code, output label */ - g_defloclabel (labf); - labt = 0; /* Mark other label as invalid */ - } + /* Jump here around the typecase code. */ + g_defcodelabel (labf); + labt = 0; /* Mark other label as invalid */ } else if (IsClassPtr (type2) && IsClassPtr (type3)) { /* Must point to same type */ @@ -2556,7 +2631,7 @@ static int hieQuest (struct expent *lval) /* If we don't have the label defined until now, do it */ if (labt) { - g_defloclabel (labt); + g_defcodelabel (labt); } /* Setup the target expression */ @@ -2757,7 +2832,7 @@ static void Assignment (struct expent* lval) /* cc65 does not have full support for handling structs by value. Since * assigning structs is one of the more useful operations from this - * familiy, allow it here. + * family, allow it here. */ if (IsClassStruct (ltype)) { @@ -2825,7 +2900,7 @@ int hie1 (struct expent* lval) int k; k = hieQuest (lval); - switch (curtok) { + switch (CurTok.Tok) { case TOK_RPAREN: case TOK_SEMI: @@ -2894,7 +2969,7 @@ int hie0 (struct expent *lval) int k; k = hie1 (lval); - while (curtok == TOK_COMMA) { + while (CurTok.Tok == TOK_COMMA) { NextToken (); k = hie1 (lval); } @@ -3053,9 +3128,6 @@ void test (unsigned label, int cond) /* Load the value into the primary register */ exprhs (CF_FORCECHAR, k, &lval); - /* Check for the closing brace */ - ConsumeRParen (); - /* Generate the jump */ if (cond) { g_truejump (CF_NONE, label); @@ -3064,10 +3136,13 @@ void test (unsigned label, int cond) * compiler itself is one big hack...): If a semicolon follows, we * don't have a statement and may omit the jump. */ - if (curtok != TOK_SEMI) { + if (CurTok.Tok != TOK_SEMI) { g_falsejump (CF_NONE, label); } } + + /* Check for the closing brace */ + ConsumeRParen (); }