Message ID | 20200211160136.GA14027@redhat.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | dissect: introduce sym_is_local() for reporter | expand |
On Tue, Feb 11, 2020 at 05:01:36PM +0100, Oleg Nesterov wrote: > Can be used to filter out the usage of local variables. ... > diff --git a/dissect.h b/dissect.h > index efe2c0b..178dba5 100644 > --- a/dissect.h > +++ b/dissect.h > @@ -27,6 +27,11 @@ struct reporter > > extern struct symbol *dissect_ctx; > > +static inline bool sym_is_local(struct symbol *sym) > +{ > + return sym->kind == 'v' && !(sym->ctype.modifiers & MOD_TOPLEVEL); > +} > + Shouldn't MOD_STATIC be added to the test? It depends on what exactly you want for 'local'. -- Luc
On 02/12, Luc Van Oostenryck wrote: > > On Tue, Feb 11, 2020 at 05:01:36PM +0100, Oleg Nesterov wrote: > > Can be used to filter out the usage of local variables. > > ... > > > diff --git a/dissect.h b/dissect.h > > index efe2c0b..178dba5 100644 > > --- a/dissect.h > > +++ b/dissect.h > > @@ -27,6 +27,11 @@ struct reporter > > > > extern struct symbol *dissect_ctx; > > > > +static inline bool sym_is_local(struct symbol *sym) > > +{ > > + return sym->kind == 'v' && !(sym->ctype.modifiers & MOD_TOPLEVEL); > > +} > > + > > Shouldn't MOD_STATIC be added to the test? perhaps I misread bind_symbol() ... but it seems to me MOD_TOPLEVEL is enough. bind_symbol() does scope = block_scope; if (ns == NS_SYMBOL && toplevel(scope)) { mod = MOD_ADDRESSABLE | MOD_TOPLEVEL; ... sym->ctype.modifiers |= mod; } toplevel(block_scope) should be true after start_file_scope() sets "block_scope = file_scope" and until start_function_scope(), right? > It depends on what exactly you want for 'local'. Yes, it should only return T if the symbol was defined inside some function. If we have static int I; in file scope, sym_is_local() should return false and so it does, test-dissect outputs 1:12 def v I int Thanks for looking! Oleg.
On Wed, Feb 12, 2020 at 10:06:27AM +0100, Oleg Nesterov wrote: > On 02/12, Luc Van Oostenryck wrote: > > It depends on what exactly you want for 'local'. > > Yes, it should only return T if the symbol was defined inside some function. > If we have > > static int I; > > in file scope, sym_is_local() should return false and so it does, test-dissect > outputs > > 1:12 def v I int OK, then everything is fine. > Thanks for looking! You're welcome! This and the other pending ones are now pushed to main. -- Luc
diff --git a/dissect.c b/dissect.c index d9ca142..823a348 100644 --- a/dissect.c +++ b/dissect.c @@ -165,7 +165,7 @@ static inline struct symbol *expr_symbol(struct expression *expr) if (!sym) { sym = alloc_symbol(expr->pos, SYM_BAD); bind_symbol(sym, expr->symbol_name, NS_SYMBOL); - sym->ctype.modifiers = MOD_EXTERN; + sym->ctype.modifiers = MOD_EXTERN | MOD_TOPLEVEL; sym->kind = expr->op ?: 'v'; /* see EXPR_CALL */ } } diff --git a/dissect.h b/dissect.h index efe2c0b..178dba5 100644 --- a/dissect.h +++ b/dissect.h @@ -27,6 +27,11 @@ struct reporter extern struct symbol *dissect_ctx; +static inline bool sym_is_local(struct symbol *sym) +{ + return sym->kind == 'v' && !(sym->ctype.modifiers & MOD_TOPLEVEL); +} + extern void dissect(struct symbol_list *, struct reporter *); #endif diff --git a/test-dissect.c b/test-dissect.c index ece2253..c4b454c 100644 --- a/test-dissect.c +++ b/test-dissect.c @@ -37,6 +37,16 @@ static void print_usage(struct position *pos, struct symbol *sym, unsigned 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); @@ -44,8 +54,8 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym) if (!sym->ident) sym->ident = built_in_ident("__asm__"); - printf("%c %-32.*s %s\n", - sym->kind, sym->ident->len, sym->ident->name, + 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) { @@ -80,8 +90,8 @@ 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("m %.*s.%-*.*s %s\n", - si->len, si->name, + 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));
Can be used to filter out the usage of local variables. Signed-off-by: Oleg Nesterov <oleg@redhat.com> --- dissect.c | 2 +- dissect.h | 5 +++++ test-dissect.c | 18 ++++++++++++++---- 3 files changed, 20 insertions(+), 5 deletions(-)