summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org>2019-02-10 12:21:03 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-02-10 12:21:03 (GMT)
commitb4038ea16c1709367f5c84939919785686481b55 (patch) (side-by-side diff)
tree118e2ebaf20bc82d04c4b7ec49dc0030aa1a1ac8 /src
parenta80f1c42bd5f63f79aa562cde5467aaf6ca54d89 (diff)
downloadcflow-b4038ea16c1709367f5c84939919785686481b55.tar.gz
cflow-b4038ea16c1709367f5c84939919785686481b55.tar.bz2
Fix processing of typedef struct and struct declarations. Fix --xref mode.
Some constucts were processed incorrectly (see typedef.at for examples). Unit-local types were not displayed in xref mode. * src/cflow.h (symbol_temp): Rename to symbol_temp. All uses changed. * src/output.c (tree_output): In all_functions mode: print all functions without explicit caller. * src/parser.c (save_token): Process curly braces. (fake_struct): Don't restore stack upon encountering identifier or modifier. See typedef.at for testcases. (parse_variable_declaration): restore stack only if type_end is -1 (no tag encountered). See struct06 in struct.at (skip_struct): Minor change. * src/parser.h: Redefine token types as enum. * src/symbol.c (unit_local_list): New static. (static_free): Preserve unit-local symbols in unit_local_list in xref mode. (collect_symbols): Consider symbols from unit_local_list. * tests/Makefile.am: Add new testcases. * tests/testsuite.at (CFLOW_TEST): New macro. Include new testcases. * tests/struct.at: New file. * tests/typedef.at: New file. * tests/struct01.at: Remove. * tests/struct02.at: Remove. * tests/struct03.at: Remove. * tests/struct04.at: Remove. * .gitignore: Update.
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/cflow.h4
-rw-r--r--src/output.c4
-rw-r--r--src/parser.c37
-rw-r--r--src/parser.h40
-rw-r--r--src/symbol.c21
5 files changed, 63 insertions, 43 deletions
diff --git a/src/cflow.h b/src/cflow.h
index 8779a68..7728ab7 100644
--- a/src/cflow.h
+++ b/src/cflow.h
@@ -85,8 +85,8 @@ typedef struct {
enum symbol_flag {
symbol_none,
- symbol_temp, /* Temporary symbol. Must be deleted after
- processing of the current module */
+ symbol_local, /* Unit-local symbol. Must be deleted after
+ processing current compilation unit */
symbol_parm, /* Parameter */
symbol_alias /* Alias to another symbol */
};
diff --git a/src/output.c b/src/output.c
index f4d1359..bf5af1f 100644
--- a/src/output.c
+++ b/src/output.c
@@ -401,7 +401,9 @@ tree_output()
if (all_functions) {
for (i = 0; i < num; i++) {
- if (main_sym != symbols[i] && symbols[i]->source) {
+ if (main_sym != symbols[i]
+ && symbols[i]->source
+ && symbols[i]->caller == NULL) {
direct_tree(0, 0, symbols[i]);
separator();
}
diff --git a/src/parser.c b/src/parser.c
index 391fe33..39d4b7c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -379,6 +379,20 @@ save_token(TOKSTK *tokptr)
obstack_1grow(&text_stk, tokptr->type);
need_space = 0;
break;
+ case LBRACE:
+ case LBRACE0:
+ if (need_space)
+ obstack_1grow(&text_stk, ' ');
+ obstack_1grow(&text_stk, '{');
+ need_space = 1;
+ break;
+ case RBRACE:
+ case RBRACE0:
+ if (need_space)
+ obstack_1grow(&text_stk, ' ');
+ obstack_1grow(&text_stk, '}');
+ need_space = 1;
+ break;
case OP:
obstack_1grow(&text_stk, ' ');
obstack_grow(&text_stk, tokptr->token, strlen(tokptr->token));
@@ -685,9 +699,6 @@ parse_function_declaration(Ident *ident, int parm)
int
fake_struct(Ident *ident)
{
- Stackpos sp;
-
- mark(sp);
ident->type_end = -1;
if (tok.type == STRUCT) {
if (nexttoken() == IDENTIFIER) {
@@ -695,15 +706,8 @@ fake_struct(Ident *ident)
}
putback();
skip_struct();
- if (tok.type == IDENTIFIER || tok.type == MODIFIER) {
- int pos = curs-1;
- restore(sp);
- if (ident->type_end == -1) {
- /* there was no tag. Insert { ... } */
- tokdel(curs, pos - 1);
- tokins(curs, IDENTIFIER, tok.line, "{ ... }");
- debugtoken(&tok, "modified stack");
- }
+ if (tok.type == IDENTIFIER || tok.type == MODIFIER || tok.type == QUALIFIER) {
+ putback();
} else if (tok.type == '(')
return 0;
else if (tok.type != ';')
@@ -729,9 +733,9 @@ parse_variable_declaration(Ident *ident, int parm)
while (tok.type == MODIFIER || tok.type == QUALIFIER)
nexttoken();
if (tok.type == IDENTIFIER) {
- int pos = curs-1;
- restore(sp);
if (ident->type_end == -1) {
+ int pos = curs-1;
+ restore(sp);
/* there was no tag. Insert { ... } */
tokdel(curs, pos - 1);
tokins(curs, IDENTIFIER, tok.line, "{ ... }");
@@ -772,7 +776,6 @@ parse_variable_declaration(Ident *ident, int parm)
else
expression();
goto select;
- break;
case LBRACE0:
case LBRACE:
func_body();
@@ -837,8 +840,10 @@ skip_struct()
}
while (tok.type == PARM_WRAPPER) {
- if (skip_balanced('(', ')', 0) == -1)
+ if (skip_balanced('(', ')', 0) == -1) {
file_error(_("unexpected end of file in struct"), NULL);
+ return;
+ }
}
}
diff --git a/src/parser.h b/src/parser.h
index 24434b1..6415d5b 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -15,25 +15,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* tokens */
-#define WORD 257
-#define LBRACE0 258
-#define RBRACE0 259
-#define IDENTIFIER 260
-#define EXTERN 261
-#define STATIC 262
-#define TYPEDEF 263
-#define STRUCT 264
-#define MODIFIER 265
-#define OP 266
-#define UNION 267
-#define ENUM 268
-#define LBRACE '{'
-#define RBRACE '}'
-#define MEMBER_OF 269
-#define TYPE 270
-#define STRING 271
-#define PARM_WRAPPER 272
-#define QUALIFIER 273
+enum {
+ LBRACE = '{',
+ RBRACE = '}',
+ WORD = 257,
+ LBRACE0,
+ RBRACE0,
+ IDENTIFIER,
+ EXTERN,
+ STATIC,
+ TYPEDEF,
+ STRUCT,
+ MODIFIER,
+ OP,
+ UNION,
+ ENUM,
+ MEMBER_OF,
+ TYPE,
+ STRING,
+ PARM_WRAPPER,
+ QUALIFIER
+};
typedef struct {
char *str;
diff --git a/src/symbol.c b/src/symbol.c
index e4cf657..a4ca34f 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -23,6 +23,7 @@ static Hash_table *symbol_table;
static struct linked_list *static_symbol_list;
static struct linked_list *auto_symbol_list;
static struct linked_list *static_func_list;
+static struct linked_list *unit_local_list;
static void
append_symbol(struct linked_list **plist, Symbol *sp)
@@ -99,7 +100,7 @@ install(char *name, int flags)
if (((flags & INSTALL_CHECK_LOCAL) &&
canonical_filename && strcmp(filename, canonical_filename)) ||
(flags & INSTALL_UNIT_LOCAL)) {
- sym->flag = symbol_temp;
+ sym->flag = symbol_local;
append_symbol(&static_symbol_list, sym);
} else
sym->flag = symbol_none;
@@ -222,9 +223,17 @@ static_free(void *data)
if (!t)
return;
- if (sym->flag == symbol_temp)
- delete_symbol(sym);
- else {
+ if (sym->flag == symbol_local) {
+ /* In xref mode, eligible unit-local symbols are retained in
+ unit_local_list for further processing.
+ Otherwise, they are deleted. */
+ if (print_option == PRINT_XREF && include_symbol(sym)) {
+ unlink_symbol(sym);
+ linked_list_append(&unit_local_list, sym);
+ } else {
+ delete_symbol(sym);
+ }
+ } else {
unlink_symbol(sym);
if (symbol_is_function(sym))
linked_list_append(&static_func_list, sym);
@@ -317,12 +326,14 @@ collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p),
size_t size;
size = hash_get_n_entries(symbol_table)
- + linked_list_size(static_func_list);
+ + linked_list_size(static_func_list)
+ + linked_list_size(unit_local_list);
cdata.sym = xcalloc(size + reserved_slots, sizeof(*cdata.sym));
cdata.index = 0;
cdata.sel = sel;
hash_do_for_each(symbol_table, collect_processor, &cdata);
linked_list_iterate(&static_func_list, collect_list_entry, &cdata);
+ linked_list_iterate(&unit_local_list, collect_list_entry, &cdata);
cdata.sym = xrealloc(cdata.sym,
(cdata.index + reserved_slots) * sizeof(*cdata.sym));

Return to:

Send suggestions and report system problems to the System administrator.