dissect: set sym->kind for reporter
PATCH 1/2 dissect: set sym->kind for reporter
Change dissect to report ctags-like kind passed in sym->kind. Currently only v,f,s and m kinds are possible.
SYM_UNION doesn't differ from SYM_STRUCT and has ->kind = 's'.
--- dissect.c | 19 ++++++++++++++----- test-dissect.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-)
dissect.c +14 -5
@@ -123,6 +123,7 @@ static inline struct symbol *no_member(struct ident *name) {static struct symbol sym = { .type =SYM_BAD , + .kind ='m' , }; sym.ctype.base_type = &bad_ctype;
@@ -165,6 +166,7 @@ static inline struct symbol *expr_symbol(struct expression *expr) sym =alloc_symbol (expr->pos,SYM_BAD );bind_symbol (sym, expr->symbol_name,NS_SYMBOL ); sym->ctype.modifiers =MOD_EXTERN ; + sym->kind ='v' ; } }
@@ -206,20 +208,20 @@ static bool deanon(struct symbol *base, struct ident *node, struct symbol *parenstatic void report_memdef (struct symbol *sym,struct symbol *mem) { + mem->kind ='m' ;if (sym && mem->ident) reporter->r_memdef (sym, mem); }static void examine_sym_node (struct symbol *node,struct symbol *parent) { +struct ident *name = node->ident;struct symbol *base, *dctx; -struct ident *name;if (node->examined)return ; - node->examined =1 ; - name = node->ident; + node->kind ='v' ;while ((base = node->ctype.base_type) !=NULL )switch (base->type) {
@@ -230,16 +232,23 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent)case SYM_ARRAY :do_expression (U_R_VAL , base->array_size); -case SYM_PTR :case SYM_FN : +case SYM_PTR : + node = base; +break ; + +case SYM_FN : + node->kind ='f' ; node = base;break ;case SYM_STRUCT :case SYM_UNION ://case SYM_ENUM: if (base->evaluated)return ; + base->evaluated =1 ; + base->kind ='s' ; +if (!base->symbol_list)return ; - base->evaluated =1 ; dctx = dissect_ctx; dissect_ctx =NULL ;
test-dissect.c +30 -4
@@ -32,7 +32,7 @@ static void print_usage(struct position *pos, struct symbol *sym, unsigned mode)if (dissect_ctx) ctx = dissect_ctx->ident; -printf ("%4d:%-3d %-16.*s %-5.3s" , +printf ("%4d:%-3d %-16.*s %s " , pos->line, pos->pos, ctx->len, ctx->name,show_mode (mode)); }
@@ -44,9 +44,30 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)if (!sym->ident) sym->ident =built_in_ident ("__asm__" ); -printf ("%-32.*s %s\n" , - sym->ident->len, sym->ident->name, +printf ("%c %-32.*s %s\n" , + sym->kind, sym->ident->len, sym->ident->name,show_typename (sym->ctype.base_type)); + +switch (sym->kind) { +case 's' : +if (sym->type ==SYM_STRUCT || sym->type ==SYM_UNION ) +break ; + goto err; + +case 'f' : +if (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)
@@ -59,10 +80,15 @@ static void r_member(unsigned mode, struct position *pos, struct symbol *sym, st/* mem == NULL means entire struct accessed */ mi = mem ? mem->ident :built_in_ident ("*" ); -printf ("%.*s.%-*.*s %s\n" , +printf ("m %.*s.%-*.*s %s\n" , 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)
Signature · 1 line
2.5.0
PATCH 2/2 dissect: enforce sym->kind='f' when it looks like a function call
A separate change for documentation purposes.
dissect() tries to work even if the parsed code is buggy or incomplete, thus it makes sense to change expr_symbol() to set kind = 'f' when it likely looks like a function name.
We can safely abuse EXPR_SYMBOL->op to pass the hint to expr_symbol(), it must be 0.
Test-case:
void call(void)
{
func();
}before this patch
1:14 def f call void ( ... ) 3:17 call --r v func bad type
after:
1:14 def f call void ( ... ) 3:17 call --r f func bad type
--- dissect.c | 4 +++- test-dissect.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
dissect.c +3 -1
@@ -166,7 +166,7 @@ static inline struct symbol *expr_symbol(struct expression *expr) sym =alloc_symbol (expr->pos,SYM_BAD );bind_symbol (sym, expr->symbol_name,NS_SYMBOL ); sym->ctype.modifiers =MOD_EXTERN ; - sym->kind ='v' ; + sym->kind = expr->op ?:'v' ;/* see EXPR_CALL */ } }
@@ -374,6 +374,8 @@ again: ret =do_expression (mode, expr->cond_false);break ;case EXPR_CALL : +if (expr->fn->type ==EXPR_SYMBOL ) + expr->fn->op ='f' ;/* for expr_symbol() */ ret =do_expression (U_R_PTR , expr->fn);if (is_ptr (ret)) ret = ret->ctype.base_type;
test-dissect.c +1 -1
@@ -55,7 +55,7 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym) goto err;case 'f' : -if (sym->ctype.base_type->type !=SYM_FN ) +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 )
Signature · 1 line
2.5.0
Quoted 6 lines · Oleg Nesterov
Change dissect to report ctags-like kind passed in
sym->kind. Currently only v,f,s and m kinds are possible.
SYM_UNIONdoesn't differ fromSYM_STRUCTand has ->kind = 's'.Signed-off-by Oleg Nesterov <[email protected]>
Thanks.
Both patches applied and pushed.
-- Luc