aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-09-07 15:41:17 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-09-07 15:41:17 +0000
commitaf5a05d17aaeffb28124198ce64a508449deb75e (patch)
tree4ba390ee8eb27324a8907f6bd417db0d8fcfcd3a
parentc06c96201c375be53db27819d3b4e61305ceecaf (diff)
downloadcflow-af5a05d17aaeffb28124198ce64a508449deb75e.tar.gz
cflow-af5a05d17aaeffb28124198ce64a508449deb75e.tar.bz2
(declare, parse_dcl, parse_knr_dcl): Fix parsing of K&R declarations, broken by modifications on 2005-09-21.
-rw-r--r--src/parser.c124
1 files changed, 64 insertions, 60 deletions
diff --git a/src/parser.c b/src/parser.c
index f1b9d53..30bc9c9 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -27,19 +27,19 @@ typedef struct {
enum storage storage;
} Ident;
void parse_declaration(Ident*, int);
void parse_variable_declaration(Ident*, int);
void parse_function_declaration(Ident*, int);
-void parse_dcl(Ident*);
+void parse_dcl(Ident*, int maybe_knr);
void parse_knr_dcl(Ident*);
void parse_typedef();
void expression();
void initializer_list();
void func_body();
-void declare(Ident*);
+void declare(Ident*, int maybe_knr);
void declare_type(Ident*);
int dcl(Ident*);
int parmdcl(Ident*);
int dirdcl(Ident*);
void skip_struct();
Symbol *get_symbol(char *name);
@@ -537,13 +537,13 @@ parse_variable_declaration(Ident *ident, int parm)
if (tok.type == ';')
return;
restore(sp);
}
}
again:
- parse_dcl(ident);
+ parse_dcl(ident, 0);
select:
switch (tok.type) {
case ')':
if (parm)
break;
@@ -610,64 +610,13 @@ initializer_list()
}
void
parse_knr_dcl(Ident *ident)
{
ident->type_end = -1;
- parse_dcl(ident);
- if (strict_ansi)
- return;
-
- switch (tok.type) {
- case IDENTIFIER:
- case TYPE:
- case STRUCT:
- if (ident->parmcnt >= 0) {
- /* maybe K&R function definition */
- int parmcnt, stop;
- Stackpos sp, new_sp;
- Ident id;
-
- mark(sp);
- parmcnt = 0;
-
- for (stop = 0; !stop && parmcnt < ident->parmcnt;
- nexttoken()) {
- id.type_end = -1;
- switch (tok.type) {
- case LBRACE:
- case LBRACE0:
- putback();
- stop = 1;
- break;
- case TYPE:
- case IDENTIFIER:
- case STRUCT:
- putback();
- mark(new_sp);
- if (dcl(&id) == 0) {
- parmcnt++;
- if (tok.type == ',') {
- do {
- tos = id.type_end; /* ouch! */
- restore(new_sp);
- dcl(&id);
- } while (tok.type == ',');
- } else if (tok.type != ';')
- putback();
- break;
- }
- /* else */
- /* FALLTHRU */
- default:
- restore(sp);
- return;
- }
- }
- }
- }
+ parse_dcl(ident, !strict_ansi);
}
void
skip_struct()
{
int lev = 0;
@@ -714,21 +663,21 @@ parse_typedef()
dcl(&ident);
if (ident.name)
declare_type(&ident);
}
void
-parse_dcl(Ident *ident)
+parse_dcl(Ident *ident, int maybe_knr)
{
ident->parmcnt = -1;
ident->name = NULL;
putback();
dcl(ident);
save_stack();
if (ident->name)
- declare(ident);
+ declare(ident, maybe_knr);
else
undo_save_stack();
}
int
dcl(Ident *idptr)
@@ -944,14 +893,67 @@ func_body()
file_error(_("unexpected end of file in function body"), 0);
return;
}
}
}
+int
+get_knr_args(Ident *ident)
+{
+ int parmcnt, stop;
+ Stackpos sp, new_sp;
+ Ident id;
+
+ switch (tok.type) {
+ case IDENTIFIER:
+ case TYPE:
+ case STRUCT:
+ /* maybe K&R function definition */
+
+ mark(sp);
+ parmcnt = 0;
+
+ for (stop = 0; !stop && parmcnt < ident->parmcnt;
+ nexttoken()) {
+ id.type_end = -1;
+ switch (tok.type) {
+ case LBRACE:
+ case LBRACE0:
+ putback();
+ stop = 1;
+ break;
+ case TYPE:
+ case IDENTIFIER:
+ case STRUCT:
+ putback();
+ mark(new_sp);
+ if (dcl(&id) == 0) {
+ parmcnt++;
+ if (tok.type == ',') {
+ do {
+ tos = id.type_end; /* ouch! */
+ restore(new_sp);
+ dcl(&id);
+ } while (tok.type == ',');
+ } else if (tok.type != ';')
+ putback();
+ break;
+ }
+ /* else */
+ /* FALLTHRU */
+ default:
+ restore(sp);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
void
-declare(Ident *ident)
+declare(Ident *ident, int maybe_knr)
{
Symbol *sp;
if (ident->storage == AutoStorage) {
undo_save_stack();
sp = install(ident->name);
@@ -962,14 +964,16 @@ declare(Ident *ident)
sp->flag = symbol_parm;
} else
sp->level = level;
sp->arity = -1;
return;
}
-
- if ((ident->parmcnt >= 0 && !(tok.type == LBRACE || tok.type == LBRACE0))
+
+ if ((ident->parmcnt >= 0
+ && (!maybe_knr || get_knr_args(ident) == 0)
+ && !(tok.type == LBRACE || tok.type == LBRACE0 || tok.type == TYPE))
|| (ident->parmcnt < 0 && ident->storage == ExplicitExternStorage)) {
undo_save_stack();
/* add_external()?? */
return;
}

Return to:

Send suggestions and report system problems to the System administrator.