Make 'show_type()' just show the type, while 'show_symbol()'
[smatch.git] / show-parse.c
blob72b3552990512b58a005bb416b82db05f9557b98
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * Print out results of parsing for debugging and testing.
7 */
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <fcntl.h>
16 #include "lib.h"
17 #include "token.h"
18 #include "parse.h"
19 #include "symbol.h"
20 #include "scope.h"
21 #include "expression.h"
24 * Symbol type printout. The type system is by far the most
25 * complicated part of C - everything else is trivial.
27 const char *modifier_string(unsigned long mod)
29 static char buffer[100];
30 char *p = buffer;
31 const char *res,**ptr, *names[] = {
32 "auto", "register", "static", "extern",
33 "const", "volatile", "[signed]", "[unsigned]",
34 "[char]", "[short]", "[long]", "[long]",
35 "[typdef]", "[structof]", "[unionof]", "[enum]",
36 "[typeof]", "[attribute]",
37 NULL
39 ptr = names;
40 while ((res = *ptr++) != NULL) {
41 if (mod & 1) {
42 char c;
43 while ((c = *res++) != '\0')
44 *p++ = c;
45 *p++ = ' ';
47 mod >>= 1;
49 *p = 0;
50 return buffer;
53 void show_struct_member(struct symbol *sym, void *data, int flags)
55 if (flags & ITERATE_FIRST)
56 printf(" { ");
57 printf("%s:%d:%d at offset %ld", show_token(sym->token), sym->bit_size, sym->alignment, sym->offset);
58 if (flags & ITERATE_LAST)
59 printf(" } ");
60 else
61 printf(", ");
64 static void show_one_symbol(struct symbol *sym, void *sep, int flags)
66 show_symbol(sym);
67 if (!(flags & ITERATE_LAST))
68 printf("%s", (const char *)sep);
71 void show_symbol_list(struct symbol_list *list, const char *sep)
73 symbol_iterate(list, show_one_symbol, (void *)sep);
76 void show_type_list(struct symbol *sym)
78 while (sym) {
79 show_symbol(sym);
80 sym = sym->next;
84 void show_type(struct symbol *sym)
86 int i;
87 static struct ctype_name {
88 struct symbol *sym;
89 char *name;
90 } typenames[] = {
91 { & char_ctype, "char" },
92 { &uchar_ctype, "unsigned char" },
93 { & short_ctype, "short" },
94 { &ushort_ctype, "unsigned short" },
95 { & int_ctype, "int" },
96 { &uint_ctype, "unsigned int" },
97 { & long_ctype, "long" },
98 { &ulong_ctype, "unsigned long" },
99 { & llong_ctype, "long long" },
100 { &ullong_ctype, "unsigned long long" },
102 { &void_ctype, "void" },
103 { &bool_ctype, "bool" },
104 { &string_ctype, "string" },
106 { &float_ctype, "float" },
107 { &double_ctype, "double" },
108 { &ldouble_ctype,"long double" },
111 if (!sym)
112 return;
114 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++) {
115 if (typenames[i].sym == sym) {
116 printf("%s", typenames[i].name);
117 return;
121 printf("%s", modifier_string(sym->ctype.modifiers));
122 switch (sym->type) {
123 case SYM_PTR:
124 printf("*");
125 show_type(sym->ctype.base_type);
126 return;
128 case SYM_FN:
129 printf("<fn>(");
130 show_type(sym->ctype.base_type);
131 printf(")");
132 return;
134 case SYM_ARRAY:
135 printf("<array>(");
136 show_type(sym->ctype.base_type);
137 printf(")");
138 return;
140 case SYM_STRUCT:
141 printf("struct %s", show_token(sym->token));
142 return;
144 case SYM_UNION:
145 printf("union %s", show_token(sym->token));
146 return;
148 case SYM_ENUM:
149 printf("enum %s", show_token(sym->token));
150 return;
152 case SYM_NODE: {
153 struct symbol *type = sym->ctype.base_type;
154 if (!type)
155 printf("notype");
156 else
157 show_type(type);
158 printf(": %s", show_token(sym->token));
159 return;
162 default:
163 printf("strange type %d '%s' of type ", sym->type, show_token(sym->token));
164 show_type(sym->ctype.base_type);
165 return;
169 void show_symbol(struct symbol *sym)
171 show_type(sym);
174 * Show actual implementation information
176 switch (sym->type) {
177 case SYM_STRUCT:
178 symbol_iterate(sym->symbol_list, show_struct_member, NULL);
179 return;
181 case SYM_UNION:
182 symbol_iterate(sym->symbol_list, show_struct_member, NULL);
183 return;
185 case SYM_FN:
186 printf("(");
187 show_symbol_list(sym->arguments, ", ");
188 printf(")\n");
189 show_statement(sym->stmt);
190 return;
192 default:
193 break;
198 * Print out a statement
200 void show_statement(struct statement *stmt)
202 if (!stmt)
203 return;
204 switch (stmt->type) {
205 case STMT_RETURN:
206 printf("\treturn ");
207 show_expression(stmt->expression);
208 break;
209 case STMT_COMPOUND:
210 printf("{\n");
211 if (stmt->syms) {
212 printf("\t");
213 show_symbol_list(stmt->syms, "\n\t");
214 printf("\n\n");
216 show_statement_list(stmt->stmts, ";\n");
217 printf("\n}\n\n");
218 break;
219 case STMT_EXPRESSION:
220 printf("\t");
221 show_expression(stmt->expression);
222 return;
223 case STMT_IF:
224 printf("\tif (");
225 show_expression(stmt->if_conditional);
226 printf(")\n");
227 show_statement(stmt->if_true);
228 if (stmt->if_false) {
229 printf("\nelse\n");
230 show_statement(stmt->if_false);
232 break;
233 case STMT_SWITCH:
234 printf("\tswitch (");
235 show_expression(stmt->switch_expression);
236 printf(")\n");
237 show_statement(stmt->switch_statement);
238 break;
240 case STMT_CASE:
241 if (!stmt->case_expression)
242 printf("default");
243 else {
244 printf("case ");
245 show_expression(stmt->case_expression);
246 if (stmt->case_to) {
247 printf(" ... ");
248 show_expression(stmt->case_to);
251 printf(":");
252 show_statement(stmt->case_statement);
253 break;
255 case STMT_BREAK:
256 printf("\tbreak");
257 break;
259 case STMT_ITERATOR: {
260 struct statement *pre_statement = stmt->iterator_pre_statement;
261 struct expression *pre_condition = stmt->iterator_pre_condition;
262 struct statement *statement = stmt->iterator_statement;
263 struct statement *post_statement = stmt->iterator_post_statement;
264 struct expression *post_condition = stmt->iterator_post_condition;
267 * THIS IS ONLY APPROXIMATE!
269 * Real iterators are more generic than
270 * any of for/while/do-while, and can't
271 * be printed out as C without goto's
273 if (post_statement || !post_condition) {
274 printf("\tfor ( ");
275 show_statement(pre_statement);
276 printf(" ; ");
277 show_expression(pre_condition);
278 printf(" ; ");
279 show_statement(post_statement);
280 printf(" )\n");
281 show_statement(statement);
282 } else if (pre_condition) {
283 if (pre_statement) {
284 show_statement(pre_statement);
285 printf(";\n");
287 printf("\twhile (");
288 show_expression(pre_condition);
289 printf(")\n");
290 show_statement(statement);
291 } else {
292 if (pre_statement) {
293 show_statement(pre_statement);
294 printf(";\n");
296 printf("\tdo\n");
297 show_statement(statement);
298 printf("\twhile (");
299 show_expression(post_condition);
300 printf(")");
302 break;
305 default:
306 printf("WTF");
310 static void show_one_statement(struct statement *stmt, void *sep, int flags)
312 show_statement(stmt);
313 if (!(flags & ITERATE_LAST))
314 printf("%s", (const char *)sep);
317 void show_statement_list(struct statement_list *stmt, const char *sep)
319 statement_iterate(stmt, show_one_statement, (void *)sep);
322 static void show_size(struct symbol *sym)
324 if (sym)
325 printf("%d:%d", sym->bit_size, sym->alignment);
329 * Print out an expression
331 void show_expression(struct expression *expr)
333 if (!expr)
334 return;
336 printf("< (");
337 show_size(expr->ctype);
338 show_type(expr->ctype);
339 printf(") ");
340 switch (expr->type) {
341 case EXPR_BINOP:
342 show_expression(expr->left);
343 printf(" %s ", show_special(expr->op));
344 show_expression(expr->right);
345 break;
346 case EXPR_PREOP:
347 printf("%s<", show_special(expr->op));
348 show_expression(expr->unop);
349 printf(">");
350 break;
351 case EXPR_POSTOP:
352 show_expression(expr->unop);
353 printf(" %s ", show_special(expr->op));
354 break;
355 case EXPR_CONSTANT:
356 printf("%s", show_token(expr->token));
357 break;
358 case EXPR_SYMBOL:
359 if (!expr->symbol) {
360 warn(expr->token, "undefined symbol '%s'", show_token(expr->token));
361 printf("<nosymbol>");
362 break;
364 printf("<%s:", show_token(expr->symbol->token));
365 show_type(expr->symbol->ctype.base_type);
366 printf(">");
367 break;
368 case EXPR_DEREF:
369 show_expression(expr->deref);
370 printf("%s", show_special(expr->op));
371 printf("%s", show_token(expr->member));
372 break;
373 case EXPR_CAST:
374 printf("<cast>(");
375 show_type(expr->cast_type);
376 printf(")");
377 show_expression(expr->cast_expression);
378 break;
379 case EXPR_VALUE:
380 printf("(%lld)", expr->value);
381 break;
382 default:
383 printf("WTF");
385 printf(" >");