aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-02-10 14:21:03 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-02-10 14:21:03 +0200
commitb4038ea16c1709367f5c84939919785686481b55 (patch)
tree118e2ebaf20bc82d04c4b7ec49dc0030aa1a1ac8
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.
-rw-r--r--.gitignore7
-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
-rw-r--r--tests/Makefile.am7
-rw-r--r--tests/struct.at105
-rw-r--r--tests/struct02.at37
-rw-r--r--tests/struct03.at40
-rw-r--r--tests/struct04.at31
-rw-r--r--tests/testsuite.at15
-rw-r--r--tests/typedef.at (renamed from tests/struct01.at)51
13 files changed, 223 insertions, 176 deletions
diff --git a/.gitignore b/.gitignore
index 9ed9226..099af3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@
8*~ 8*~
9.bootstrap 9.bootstrap
10.deps 10.deps
11.emacs.desktop 11.emacs*
12.gdbinit 12.gdbinit
13ABOUT-NLS 13ABOUT-NLS
14ChangeLog 14ChangeLog
@@ -28,3 +28,8 @@ configure
28gnu 28gnu
29m4 29m4
30stamp-h1 30stamp-h1
31/cflow-*.tar.*
32*.cflow
33core
34tmp/
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
86enum symbol_flag { 86enum 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)
685int 699int
686fake_struct(Ident *ident) 700fake_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 18enum {
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
38typedef struct { 40typedef 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;
23static struct linked_list *static_symbol_list; 23static struct linked_list *static_symbol_list;
24static struct linked_list *auto_symbol_list; 24static struct linked_list *auto_symbol_list;
25static struct linked_list *static_func_list; 25static struct linked_list *static_func_list;
26static struct linked_list *unit_local_list;
26 27
27static void 28static void
28append_symbol(struct linked_list **plist, Symbol *sp) 29append_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) {