diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-02-10 14:21:03 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-02-10 14:21:03 +0200 |
commit | b4038ea16c1709367f5c84939919785686481b55 (patch) | |
tree | 118e2ebaf20bc82d04c4b7ec49dc0030aa1a1ac8 | |
parent | a80f1c42bd5f63f79aa562cde5467aaf6ca54d89 (diff) | |
download | cflow-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.
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | src/cflow.h | 4 | ||||
-rw-r--r-- | src/output.c | 4 | ||||
-rw-r--r-- | src/parser.c | 37 | ||||
-rw-r--r-- | src/parser.h | 40 | ||||
-rw-r--r-- | src/symbol.c | 21 | ||||
-rw-r--r-- | tests/Makefile.am | 7 | ||||
-rw-r--r-- | tests/struct.at | 105 | ||||
-rw-r--r-- | tests/struct02.at | 37 | ||||
-rw-r--r-- | tests/struct03.at | 40 | ||||
-rw-r--r-- | tests/struct04.at | 31 | ||||
-rw-r--r-- | tests/testsuite.at | 15 | ||||
-rw-r--r-- | tests/typedef.at (renamed from tests/struct01.at) | 51 |
13 files changed, 223 insertions, 176 deletions
@@ -8,7 +8,7 @@ | |||
8 | *~ | 8 | *~ |
9 | .bootstrap | 9 | .bootstrap |
10 | .deps | 10 | .deps |
11 | .emacs.desktop | 11 | .emacs* |
12 | .gdbinit | 12 | .gdbinit |
13 | ABOUT-NLS | 13 | ABOUT-NLS |
14 | ChangeLog | 14 | ChangeLog |
@@ -28,3 +28,8 @@ configure | |||
28 | gnu | 28 | gnu |
29 | m4 | 29 | m4 |
30 | stamp-h1 | 30 | stamp-h1 |
31 | /cflow-*.tar.* | ||
32 | *.cflow | ||
33 | core | ||
34 | tmp/ | ||
35 | *.patch | ||
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 { | |||
85 | 85 | ||
86 | enum symbol_flag { | 86 | enum symbol_flag { |
87 | symbol_none, | 87 | symbol_none, |
88 | symbol_temp, /* Temporary symbol. Must be deleted after | 88 | symbol_local, /* Unit-local symbol. Must be deleted after |
89 | processing of the current module */ | 89 | processing current compilation unit */ |
90 | symbol_parm, /* Parameter */ | 90 | symbol_parm, /* Parameter */ |
91 | symbol_alias /* Alias to another symbol */ | 91 | symbol_alias /* Alias to another symbol */ |
92 | }; | 92 | }; |
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() | |||
401 | 401 | ||
402 | if (all_functions) { | 402 | if (all_functions) { |
403 | for (i = 0; i < num; i++) { | 403 | for (i = 0; i < num; i++) { |
404 | if (main_sym != symbols[i] && symbols[i]->source) { | 404 | if (main_sym != symbols[i] |
405 | && symbols[i]->source | ||
406 | && symbols[i]->caller == NULL) { | ||
405 | direct_tree(0, 0, symbols[i]); | 407 | direct_tree(0, 0, symbols[i]); |
406 | separator(); | 408 | separator(); |
407 | } | 409 | } |
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) | |||
379 | obstack_1grow(&text_stk, tokptr->type); | 379 | obstack_1grow(&text_stk, tokptr->type); |
380 | need_space = 0; | 380 | need_space = 0; |
381 | break; | 381 | break; |
382 | case LBRACE: | ||
383 | case LBRACE0: | ||
384 | if (need_space) | ||
385 | obstack_1grow(&text_stk, ' '); | ||
386 | obstack_1grow(&text_stk, '{'); | ||
387 | need_space = 1; | ||
388 | break; | ||
389 | case RBRACE: | ||
390 | case RBRACE0: | ||
391 | if (need_space) | ||
392 | obstack_1grow(&text_stk, ' '); | ||
393 | obstack_1grow(&text_stk, '}'); | ||
394 | need_space = 1; | ||
395 | break; | ||
382 | case OP: | 396 | case OP: |
383 | obstack_1grow(&text_stk, ' '); | 397 | obstack_1grow(&text_stk, ' '); |
384 | obstack_grow(&text_stk, tokptr->token, strlen(tokptr->token)); | 398 | obstack_grow(&text_stk, tokptr->token, strlen(tokptr->token)); |
@@ -685,9 +699,6 @@ parse_function_declaration(Ident *ident, int parm) | |||
685 | int | 699 | int |
686 | fake_struct(Ident *ident) | 700 | fake_struct(Ident *ident) |
687 | { | 701 | { |
688 | Stackpos sp; | ||
689 | |||
690 | mark(sp); | ||
691 | ident->type_end = -1; | 702 | ident->type_end = -1; |
692 | if (tok.type == STRUCT) { | 703 | if (tok.type == STRUCT) { |
693 | if (nexttoken() == IDENTIFIER) { | 704 | if (nexttoken() == IDENTIFIER) { |
@@ -695,15 +706,8 @@ fake_struct(Ident *ident) | |||
695 | } | 706 | } |
696 | putback(); | 707 | putback(); |
697 | skip_struct(); | 708 | skip_struct(); |
698 | if (tok.type == IDENTIFIER || tok.type == MODIFIER) { | 709 | if (tok.type == IDENTIFIER || tok.type == MODIFIER || tok.type == QUALIFIER) { |
699 | int pos = curs-1; | 710 | putback(); |
700 | restore(sp); | ||
701 | if (ident->type_end == -1) { | ||
702 | /* there was no tag. Insert { ... } */ | ||
703 | tokdel(curs, pos - 1); | ||
704 | tokins(curs, IDENTIFIER, tok.line, "{ ... }"); | ||
705 | debugtoken(&tok, "modified stack"); | ||
706 | } | ||
707 | } else if (tok.type == '(') | 711 | } else if (tok.type == '(') |
708 | return 0; | 712 | return 0; |
709 | else if (tok.type != ';') | 713 | else if (tok.type != ';') |
@@ -729,9 +733,9 @@ parse_variable_declaration(Ident *ident, int parm) | |||
729 | while (tok.type == MODIFIER || tok.type == QUALIFIER) | 733 | while (tok.type == MODIFIER || tok.type == QUALIFIER) |
730 | nexttoken(); | 734 | nexttoken(); |
731 | if (tok.type == IDENTIFIER) { | 735 | if (tok.type == IDENTIFIER) { |
732 | int pos = curs-1; | ||
733 | restore(sp); | ||
734 | if (ident->type_end == -1) { | 736 | if (ident->type_end == -1) { |
737 | int pos = curs-1; | ||
738 | restore(sp); | ||
735 | /* there was no tag. Insert { ... } */ | 739 | /* there was no tag. Insert { ... } */ |
736 | tokdel(curs, pos - 1); | 740 | tokdel(curs, pos - 1); |
737 | tokins(curs, IDENTIFIER, tok.line, "{ ... }"); | 741 | tokins(curs, IDENTIFIER, tok.line, "{ ... }"); |
@@ -772,7 +776,6 @@ parse_variable_declaration(Ident *ident, int parm) | |||
772 | else | 776 | else |
773 | expression(); | 777 | expression(); |
774 | goto select; | 778 | goto select; |
775 | break; | ||
776 | case LBRACE0: | 779 | case LBRACE0: |
777 | case LBRACE: | 780 | case LBRACE: |
778 | func_body(); | 781 | func_body(); |
@@ -837,8 +840,10 @@ skip_struct() | |||
837 | } | 840 | } |
838 | 841 | ||
839 | while (tok.type == PARM_WRAPPER) { | 842 | while (tok.type == PARM_WRAPPER) { |
840 | if (skip_balanced('(', ')', 0) == -1) | 843 | if (skip_balanced('(', ')', 0) == -1) { |
841 | file_error(_("unexpected end of file in struct"), NULL); | 844 | file_error(_("unexpected end of file in struct"), NULL); |
845 | return; | ||
846 | } | ||
842 | } | 847 | } |
843 | } | 848 | } |
844 | 849 | ||
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 @@ | |||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | /* tokens */ | 17 | /* tokens */ |
18 | #define WORD 257 | 18 | enum { |
19 | #define LBRACE0 258 | 19 | LBRACE = '{', |
20 | #define RBRACE0 259 | 20 | RBRACE = '}', |
21 | #define IDENTIFIER 260 | 21 | WORD = 257, |
22 | #define EXTERN 261 | 22 | LBRACE0, |
23 | #define STATIC 262 | 23 | RBRACE0, |
24 | #define TYPEDEF 263 | 24 | IDENTIFIER, |
25 | #define STRUCT 264 | 25 | EXTERN, |
26 | #define MODIFIER 265 | 26 | STATIC, |
27 | #define OP 266 | 27 | TYPEDEF, |
28 | #define UNION 267 | 28 | STRUCT, |
29 | #define ENUM 268 | 29 | MODIFIER, |
30 | #define LBRACE '{' | 30 | OP, |
31 | #define RBRACE '}' | 31 | UNION, |
32 | #define MEMBER_OF 269 | 32 | ENUM, |
33 | #define TYPE 270 | 33 | MEMBER_OF, |
34 | #define STRING 271 | 34 | TYPE, |
35 | #define PARM_WRAPPER 272 | 35 | STRING, |
36 | #define QUALIFIER 273 | 36 | PARM_WRAPPER, |
37 | QUALIFIER | ||
38 | }; | ||
37 | 39 | ||
38 | typedef struct { | 40 | typedef struct { |
39 | char *str; | 41 | 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; | |||
23 | static struct linked_list *static_symbol_list; | 23 | static struct linked_list *static_symbol_list; |
24 | static struct linked_list *auto_symbol_list; | 24 | static struct linked_list *auto_symbol_list; |
25 | static struct linked_list *static_func_list; | 25 | static struct linked_list *static_func_list; |
26 | static struct linked_list *unit_local_list; | ||
26 | 27 | ||
27 | static void | 28 | static void |
28 | append_symbol(struct linked_list **plist, Symbol *sp) | 29 | append_symbol(struct linked_list **plist, Symbol *sp) |
@@ -99,7 +100,7 @@ install(char *name, int flags) | |||
99 | if (((flags & INSTALL_CHECK_LOCAL) && | 100 | if (((flags & INSTALL_CHECK_LOCAL) && |
100 | canonical_filename && strcmp(filename, canonical_filename)) || | 101 | canonical_filename && strcmp(filename, canonical_filename)) || |
101 | (flags & INSTALL_UNIT_LOCAL)) { | 102 | (flags & INSTALL_UNIT_LOCAL)) { |
102 | sym->flag = symbol_temp; | 103 | sym->flag = symbol_local; |
103 | append_symbol(&static_symbol_list, sym); | 104 | append_symbol(&static_symbol_list, sym); |
104 | } else | 105 | } else |
105 | sym->flag = symbol_none; | 106 | sym->flag = symbol_none; |
@@ -222,9 +223,17 @@ static_free(void *data) | |||
222 | 223 | ||
223 | if (!t) | 224 | if (!t) |
224 | return; | 225 | return; |
225 | if (sym->flag == symbol_temp) | 226 | if (sym->flag == symbol_local) { |