mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Improved error recovery with type cast and sizeof.
This commit is contained in:
parent
a1a060c291
commit
cadf8012f6
@ -2166,20 +2166,41 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
|
||||
|
||||
|
||||
Type* ParseType (Type* T)
|
||||
/* Parse a complete type specification */
|
||||
/* Parse a complete type specification in parentheses */
|
||||
{
|
||||
DeclSpec Spec;
|
||||
Declarator Decl;
|
||||
int NeedClean = -1;
|
||||
|
||||
/* Skip the left paren */
|
||||
NextToken ();
|
||||
|
||||
/* Get a type without a default */
|
||||
InitDeclSpec (&Spec);
|
||||
ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE);
|
||||
|
||||
/* Parse additional declarators */
|
||||
ParseDecl (&Spec, &Decl, DM_NO_IDENT);
|
||||
/* Only parse further if there is a type specifier */
|
||||
if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) {
|
||||
/* Parse additional declarators */
|
||||
NeedClean = ParseDecl (&Spec, &Decl, DM_NO_IDENT);
|
||||
|
||||
/* Copy the type to the target buffer */
|
||||
TypeCopy (T, Decl.Type);
|
||||
/* Copy the type to the target buffer */
|
||||
TypeCopy (T, Decl.Type);
|
||||
} else {
|
||||
/* Fail-safe */
|
||||
TypeCopy (T, type_int);
|
||||
}
|
||||
|
||||
/* Try some smart error recovery */
|
||||
if (NeedClean < 0) {
|
||||
SimpleErrorSkip ();
|
||||
}
|
||||
|
||||
/* Closing paren */
|
||||
if (!ConsumeRParen ()) {
|
||||
SimpleErrorSkip ();
|
||||
NextToken ();
|
||||
}
|
||||
|
||||
/* Return a pointer to the target buffer */
|
||||
return T;
|
||||
|
@ -135,7 +135,7 @@ typedef enum {
|
||||
|
||||
|
||||
Type* ParseType (Type* Type);
|
||||
/* Parse a complete type specification */
|
||||
/* Parse a complete type specification in parentheses */
|
||||
|
||||
int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode);
|
||||
/* Parse a variable, type or function declarator. Return -1 if this stops at
|
||||
|
@ -1415,24 +1415,8 @@ static void Primary (ExprDesc* E)
|
||||
ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO);
|
||||
|
||||
if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) {
|
||||
/* Recognized but not supported */
|
||||
Error ("Mixed declarations and code are not supported in cc65");
|
||||
|
||||
while (CurTok.Tok != TOK_SEMI) {
|
||||
Declarator Decl;
|
||||
|
||||
/* Parse one declaration */
|
||||
ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY);
|
||||
if (CurTok.Tok == TOK_ASSIGN) {
|
||||
NextToken ();
|
||||
ParseInit (Decl.Type);
|
||||
}
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextToken ();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SmartErrorSkip (0);
|
||||
} else {
|
||||
Error ("Expression expected");
|
||||
E->Flags |= E_EVAL_MAYBE_UNUSED;
|
||||
@ -2089,9 +2073,7 @@ void hie10 (ExprDesc* Expr)
|
||||
NextToken ();
|
||||
if (TypeSpecAhead ()) {
|
||||
Type T[MAXTYPELEN];
|
||||
NextToken ();
|
||||
Size = ExprCheckedSizeOf (ParseType (T));
|
||||
ConsumeRParen ();
|
||||
} else {
|
||||
/* Remember the output queue pointer */
|
||||
CodeMark Mark;
|
||||
|
@ -1392,6 +1392,55 @@ ExitPoint:
|
||||
|
||||
|
||||
|
||||
int SimpleErrorSkip (void)
|
||||
/* Skip tokens until an EOF or unpaired right parenthesis/bracket/curly brace
|
||||
** is reached. Return 0 If this exits at an EOF. Otherwise return -1.
|
||||
*/
|
||||
{
|
||||
Collection C = AUTO_COLLECTION_INITIALIZER;
|
||||
int Res = 0;
|
||||
|
||||
/* Some fix point tokens that are used for error recovery */
|
||||
static const token_t TokenList[] = {
|
||||
TOK_LPAREN, TOK_RPAREN, TOK_LBRACK, TOK_RBRACK, TOK_LCURLY, TOK_RCURLY };
|
||||
|
||||
while (CurTok.Tok != TOK_CEOF) {
|
||||
SkipTokens (TokenList, sizeof (TokenList) / sizeof (TokenList[0]));
|
||||
|
||||
switch (CurTok.Tok) {
|
||||
case TOK_LPAREN:
|
||||
case TOK_LBRACK:
|
||||
case TOK_LCURLY:
|
||||
OpenBrace (&C, CurTok.Tok);
|
||||
break;
|
||||
|
||||
case TOK_RPAREN:
|
||||
case TOK_RBRACK:
|
||||
case TOK_RCURLY:
|
||||
if (CloseBrace (&C, CurTok.Tok) < 0) {
|
||||
/* Found a terminator */
|
||||
Res = -1;
|
||||
goto ExitPoint;
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_CEOF:
|
||||
/* We cannot go any farther */
|
||||
Res = 0;
|
||||
goto ExitPoint;
|
||||
|
||||
default:
|
||||
Internal ("Unexpected token: %02X", (unsigned)CurTok.Tok);
|
||||
}
|
||||
}
|
||||
|
||||
ExitPoint:
|
||||
DoneCollection (&C);
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Consume (token_t Token, const char* ErrorMsg)
|
||||
/* Eat token if it is the next in the input stream, otherwise print an error
|
||||
** message. Returns true if the token was found and false otherwise.
|
||||
|
@ -339,6 +339,11 @@ int SmartErrorSkip (int TillEnd);
|
||||
** If this exits at a non-EOF without consuming it.
|
||||
*/
|
||||
|
||||
int SimpleErrorSkip (void);
|
||||
/* Skip tokens until an EOF or unpaired right parenthesis/bracket/curly brace
|
||||
** is reached. Return 0 If this exits at an EOF. Otherwise return -1.
|
||||
*/
|
||||
|
||||
int Consume (token_t Token, const char* ErrorMsg);
|
||||
/* Eat token if it is the next in the input stream, otherwise print an error
|
||||
** message. Returns true if the token was found and false otherwise.
|
||||
|
@ -321,15 +321,9 @@ void TypeCast (ExprDesc* Expr)
|
||||
{
|
||||
Type NewType[MAXTYPELEN];
|
||||
|
||||
/* Skip the left paren */
|
||||
NextToken ();
|
||||
|
||||
/* Read the type */
|
||||
/* Read the type enclosed in parentheses */
|
||||
ParseType (NewType);
|
||||
|
||||
/* Closing paren */
|
||||
ConsumeRParen ();
|
||||
|
||||
/* Read the expression we have to cast */
|
||||
hie10 (Expr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user