| #include "dissect.h" |
| |
| static inline const char *show_mode(unsigned mode) |
| { |
| static char str[3]; |
| |
| if (mode == -1) |
| return "def"; |
| |
| #define U(u_r) "-rwm"[(mode / u_r) & 3] |
| str[0] = U(U_R_AOF); |
| str[1] = U(U_R_VAL); |
| str[2] = U(U_R_PTR); |
| #undef U |
| |
| return str; |
| } |
| |
| static void print_usage(struct position *pos, struct symbol *sym, unsigned mode) |
| { |
| static unsigned curr_stream = -1; |
| static struct ident null; |
| struct ident *ctx = &null; |
| |
| if (curr_stream != pos->stream) { |
| curr_stream = pos->stream; |
| printf("\nFILE: %s\n\n", stream_name(curr_stream)); |
| } |
| |
| if (dissect_ctx) |
| ctx = dissect_ctx->ident; |
| |
| printf("%4d:%-3d %-16.*s %s ", |
| pos->line, pos->pos, ctx->len, ctx->name, show_mode(mode)); |
| |
| } |
| |
| static char symscope(struct symbol *sym) |
| { |
| if (sym_is_local(sym)) { |
| if (!dissect_ctx) |
| warning(sym->pos, "no context"); |
| return '.'; |
| } |
| return ' '; |
| } |
| |
| static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym) |
| { |
| print_usage(pos, sym, mode); |
| |
| if (!sym->ident) |
| sym->ident = built_in_ident("__asm__"); |
| |
| printf("%c %c %-32.*s %s\n", |
| symscope(sym), sym->kind, sym->ident->len, sym->ident->name, |
| show_typename(sym->ctype.base_type)); |
| |
| switch (sym->kind) { |
| case 'd': |
| break; |
| case 's': |
| if (sym->type == SYM_STRUCT || sym->type == SYM_UNION) |
| break; |
| goto err; |
| case 't': |
| break; |
| case 'f': |
| if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN) |
| goto err; |
| case 'v': |
| if (sym->type == SYM_NODE || sym->type == SYM_BAD) |
| break; |
| goto err; |
| default: |
| goto err; |
| } |
| |
| return; |
| err: |
| warning(*pos, "r_symbol bad sym type=%d kind=%d", sym->type, sym->kind); |
| } |
| |
| static void r_member(unsigned mode, struct position *pos, struct symbol *sym, struct symbol *mem) |
| { |
| struct ident *ni, *si, *mi; |
| |
| print_usage(pos, sym, mode); |
| |
| ni = built_in_ident("?"); |
| si = sym->ident ?: ni; |
| /* mem == NULL means entire struct accessed */ |
| mi = mem ? (mem->ident ?: ni) : built_in_ident("*"); |
| |
| printf("%c m %.*s.%-*.*s %s\n", |
| symscope(sym), si->len, si->name, |
| 32-1 - si->len, mi->len, mi->name, |
| show_typename(mem ? mem->ctype.base_type : sym)); |
| |
| if (sym->ident && sym->kind != 's') |
| warning(*pos, "r_member bad sym type=%d kind=%d", sym->type, sym->kind); |
| if (mem && mem->kind != 'm') |
| warning(*pos, "r_member bad mem->kind = %d", mem->kind); |
| } |
| |
| static void r_symdef(struct symbol *sym) |
| { |
| r_symbol(-1, &sym->pos, sym); |
| } |
| |
| static void r_memdef(struct symbol *sym, struct symbol *mem) |
| { |
| r_member(-1, &mem->pos, sym, mem); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| static struct reporter reporter = { |
| .r_symdef = r_symdef, |
| .r_memdef = r_memdef, |
| .r_symbol = r_symbol, |
| .r_member = r_member, |
| }; |
| |
| struct string_list *filelist = NULL; |
| sparse_initialize(argc, argv, &filelist); |
| dissect(&reporter, filelist); |
| |
| return 0; |
| } |