1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include "dissect.h"
static unsigned dotc_stream;
static inline char storage(struct symbol *sym)
{
int t = sym->type;
unsigned m = sym->ctype.modifiers;
if (m & MOD_INLINE || t == SYM_STRUCT || t == SYM_UNION /*|| t == SYM_ENUM*/)
return sym->pos.stream == dotc_stream ? 's' : 'g';
return (m & MOD_STATIC) ? 's' : (m & MOD_NONLOCAL) ? 'g' : 'l';
}
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;
if (curr_stream != pos->stream) {
curr_stream = pos->stream;
printf("\nFILE: %s\n\n", stream_name(curr_stream));
}
printf("%4d:%-3d %c %-5.3s",
pos->line, pos->pos, storage(sym), show_mode(mode));
}
static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
{
print_usage(pos, sym, mode);
if (!sym->ident)
sym->ident = MK_IDENT("__asm__");
printf("%-32.*s %s\n",
sym->ident->len, sym->ident->name,
show_typename(sym->ctype.base_type));
}
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 = MK_IDENT("?");
si = sym->ident ?: ni;
/* mem == NULL means entire struct accessed */
mi = mem ? (mem->ident ?: ni) : MK_IDENT("*");
printf("%.*s.%-*.*s %s\n",
si->len, si->name,
32-1 - si->len, mi->len, mi->name,
show_typename(mem ? mem->ctype.base_type : sym));
}
static void r_symdef(struct symbol *sym)
{
r_symbol(-1, &sym->pos, sym);
}
int main(int argc, char **argv)
{
static struct reporter reporter = {
.r_symdef = r_symdef,
.r_symbol = r_symbol,
.r_member = r_member,
};
struct string_list *filelist = NULL;
char *file;
sparse_initialize(argc, argv, &filelist);
FOR_EACH_PTR_NOTAG(filelist, file) {
dotc_stream = input_stream_nr;
dissect(__sparse(file), &reporter);
} END_FOR_EACH_PTR_NOTAG(file);
return 0;
}
|