1f08c3bdfSopenharmony_ci#include "dissect.h"
2f08c3bdfSopenharmony_ci
3f08c3bdfSopenharmony_cistatic inline const char *show_mode(unsigned mode)
4f08c3bdfSopenharmony_ci{
5f08c3bdfSopenharmony_ci	static char str[3];
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci	if (mode == -1)
8f08c3bdfSopenharmony_ci		return "def";
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ci#define	U(u_r)	"-rwm"[(mode / u_r) & 3]
11f08c3bdfSopenharmony_ci	str[0] = U(U_R_AOF);
12f08c3bdfSopenharmony_ci	str[1] = U(U_R_VAL);
13f08c3bdfSopenharmony_ci	str[2] = U(U_R_PTR);
14f08c3bdfSopenharmony_ci#undef	U
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci	return str;
17f08c3bdfSopenharmony_ci}
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_cistatic void print_usage(struct position *pos, struct symbol *sym, unsigned mode)
20f08c3bdfSopenharmony_ci{
21f08c3bdfSopenharmony_ci	static unsigned curr_stream = -1;
22f08c3bdfSopenharmony_ci	static struct ident null;
23f08c3bdfSopenharmony_ci	struct ident *ctx = &null;
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci	if (curr_stream != pos->stream) {
26f08c3bdfSopenharmony_ci		curr_stream = pos->stream;
27f08c3bdfSopenharmony_ci		printf("\nFILE: %s\n\n", stream_name(curr_stream));
28f08c3bdfSopenharmony_ci	}
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci	if (dissect_ctx)
31f08c3bdfSopenharmony_ci		ctx = dissect_ctx->ident;
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci	printf("%4d:%-3d %-16.*s %s ",
34f08c3bdfSopenharmony_ci		pos->line, pos->pos, ctx->len, ctx->name, show_mode(mode));
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci}
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_cistatic char symscope(struct symbol *sym)
39f08c3bdfSopenharmony_ci{
40f08c3bdfSopenharmony_ci	if (sym_is_local(sym)) {
41f08c3bdfSopenharmony_ci		if (!dissect_ctx)
42f08c3bdfSopenharmony_ci			warning(sym->pos, "no context");
43f08c3bdfSopenharmony_ci		return '.';
44f08c3bdfSopenharmony_ci	}
45f08c3bdfSopenharmony_ci	return ' ';
46f08c3bdfSopenharmony_ci}
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_cistatic void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
49f08c3bdfSopenharmony_ci{
50f08c3bdfSopenharmony_ci	print_usage(pos, sym, mode);
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	if (!sym->ident)
53f08c3bdfSopenharmony_ci		sym->ident = built_in_ident("__asm__");
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci	printf("%c %c %-32.*s %s\n",
56f08c3bdfSopenharmony_ci		symscope(sym), sym->kind, sym->ident->len, sym->ident->name,
57f08c3bdfSopenharmony_ci		show_typename(sym->ctype.base_type));
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	switch (sym->kind) {
60f08c3bdfSopenharmony_ci	case 's':
61f08c3bdfSopenharmony_ci		if (sym->type == SYM_STRUCT || sym->type == SYM_UNION)
62f08c3bdfSopenharmony_ci			break;
63f08c3bdfSopenharmony_ci		goto err;
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci	case 'f':
66f08c3bdfSopenharmony_ci		if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN)
67f08c3bdfSopenharmony_ci			goto err;
68f08c3bdfSopenharmony_ci	case 'v':
69f08c3bdfSopenharmony_ci		if (sym->type == SYM_NODE || sym->type == SYM_BAD)
70f08c3bdfSopenharmony_ci			break;
71f08c3bdfSopenharmony_ci		goto err;
72f08c3bdfSopenharmony_ci	default:
73f08c3bdfSopenharmony_ci		goto err;
74f08c3bdfSopenharmony_ci	}
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci	return;
77f08c3bdfSopenharmony_cierr:
78f08c3bdfSopenharmony_ci	warning(*pos, "r_symbol bad sym type=%d kind=%d", sym->type, sym->kind);
79f08c3bdfSopenharmony_ci}
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_cistatic void r_member(unsigned mode, struct position *pos, struct symbol *sym, struct symbol *mem)
82f08c3bdfSopenharmony_ci{
83f08c3bdfSopenharmony_ci	struct ident *ni, *si, *mi;
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci	print_usage(pos, sym, mode);
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_ci	ni = built_in_ident("?");
88f08c3bdfSopenharmony_ci	si = sym->ident ?: ni;
89f08c3bdfSopenharmony_ci	/* mem == NULL means entire struct accessed */
90f08c3bdfSopenharmony_ci	mi = mem ? (mem->ident ?: ni) : built_in_ident("*");
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_ci	printf("%c m %.*s.%-*.*s %s\n",
93f08c3bdfSopenharmony_ci		symscope(sym), si->len, si->name,
94f08c3bdfSopenharmony_ci		32-1 - si->len, mi->len, mi->name,
95f08c3bdfSopenharmony_ci		show_typename(mem ? mem->ctype.base_type : sym));
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_ci	if (sym->ident && sym->kind != 's')
98f08c3bdfSopenharmony_ci		warning(*pos, "r_member bad sym type=%d kind=%d", sym->type, sym->kind);
99f08c3bdfSopenharmony_ci	if (mem && mem->kind != 'm')
100f08c3bdfSopenharmony_ci		warning(*pos, "r_member bad mem->kind = %d", mem->kind);
101f08c3bdfSopenharmony_ci}
102f08c3bdfSopenharmony_ci
103f08c3bdfSopenharmony_cistatic void r_symdef(struct symbol *sym)
104f08c3bdfSopenharmony_ci{
105f08c3bdfSopenharmony_ci	r_symbol(-1, &sym->pos, sym);
106f08c3bdfSopenharmony_ci}
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_cistatic void r_memdef(struct symbol *sym, struct symbol *mem)
109f08c3bdfSopenharmony_ci{
110f08c3bdfSopenharmony_ci	r_member(-1, &mem->pos, sym, mem);
111f08c3bdfSopenharmony_ci}
112f08c3bdfSopenharmony_ci
113f08c3bdfSopenharmony_ciint main(int argc, char **argv)
114f08c3bdfSopenharmony_ci{
115f08c3bdfSopenharmony_ci	static struct reporter reporter = {
116f08c3bdfSopenharmony_ci		.r_symdef = r_symdef,
117f08c3bdfSopenharmony_ci		.r_memdef = r_memdef,
118f08c3bdfSopenharmony_ci		.r_symbol = r_symbol,
119f08c3bdfSopenharmony_ci		.r_member = r_member,
120f08c3bdfSopenharmony_ci	};
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_ci	struct string_list *filelist = NULL;
123f08c3bdfSopenharmony_ci	sparse_initialize(argc, argv, &filelist);
124f08c3bdfSopenharmony_ci	dissect(&reporter, filelist);
125f08c3bdfSopenharmony_ci
126f08c3bdfSopenharmony_ci	return 0;
127f08c3bdfSopenharmony_ci}
128