From: Konrad Eisele <konrad@gaisler.com>
To: Christopher Li <sparse@chrisli.org>
Cc: Konrad Eisele <eiselekd@gmail.com>, linux-sparse@vger.kernel.org
Subject: Re: dependency tee from c parser entities downto token
Date: Fri, 04 May 2012 09:33:09 +0200 [thread overview]
Message-ID: <4FA38635.5060300@gaisler.com> (raw)
In-Reply-To: <CANeU7QkWbvT-NN5vm=JXnmfDpbzNzTjNYxkB8GJsKCysiOe8tQ@mail.gmail.com>
Christopher Li wrote:
> On Wed, May 2, 2012 at 12:27 AM, Konrad Eisele<eiselekd@gmail.com> wrote:
>> But this is the point. All macros are expanded. They disappear completely in
>> the pre-processing step. There is no tool at all right now that
>> preserves the macro-dependency. Even in IDEs like Eclipse you have tools to show
>> macros expansions, but you have no tool to show you in a simple
>> way for i.e.:
>> #define a
>> #ifdef a
>> #define b 1
>> #endif
>> that "#define b 1" is dependent of "#define a" even the "#ifdef a" is
>> lost and you have to deduce it yourself from the #line comments.
>
> Sure, so the usage case is mostly for people to understand how
> the macro get expanded.
Yes, and in a human readable way, that is, the output is from
before the pre-procesing step. Otherwise it is meaningless.
>
>> The information for this is in "struct macro_expansion" of the patch and one can
>> build aroung it a trace of the macro expansion. I've done that with a patch for
>> gcc and could do it for sparse also. A example is at:
>> http://cfw.sourceforge.net/htmltag/init_32.c.pinfo.html
>> source at : http://cfw.sourceforge.net/htmltags.html
>> i.e. go in init_32.c.pinfo.html to mark_rodata_ro() and click on
>> virt_to_page (). A help in in the left pannel.
>
> I agree this is useful. However I feel the original patch is a bit invasive.
> How about do it in a step by step way. Make a small patch to allow register
> call backs when the macro expands. That way the application using sparse
> get notify of the pre-processor macro expands. I can take a look at how to
> implement this small patch as well.
>
> If needed, we can make one option that pre-processor don't free the tokens.
> In this case, very few changes in the caller side. I feel it cleaner
> than changing
> the free function behavior.
The minimum original-code-base change that I see would be:
- "struct position <pos>" is removed in all structures except "struct token" and
replaced with "struct token *<tok>". When <pos> is needed <tok>->pos is
used instead. This implies that tokens are not freed by default.
- struct statement *, struct expression *, struct *token
all get a extra "void *custom" pointer. This pointer can be used for
tools to save their own data.
I think this is not too far off: 4 bytes more for each struct and "<tok>->pos"
instead of "pos", that is not a massive change. the <tok>->pos would be
a boilerplate refactoring.
Should I implemnt a patch for that as a first step?
After that I can build upon that.
-- Konrad
Ps: I post again the link for my "shrinkc" app. I think
it is very impressive. I never had en overview about stdlib.h
and could see for that first time the dependencies for i.e.
FILE *f. Ok the ouput is still raw, "#include" lines are missing,
but still you can really see what is going on. And frankly,
isnt it strange that all c-programmers use stdlib.h without
really knowing what is going on? Maybe I am the only one that
has no clue though...
$git clone git://git.code.sf.net/p/decpp/code decpp
$cd decpp
$make
$./shrinkc t1.c
============= output of "shrinkc" ===============
eiselekd+~/tmp/>shrinkc t1.c
********* builtin *********
********* preprocessor *********
********* t1.c *********
int main(int argc, char **argv) {
FILE *f;
};
********* preprocessor *********
********* /usr/include/stdio.h *********
#ifndef _STDIO_H
#if !defined __need_FILE && !defined __need___FILE
# define _STDIO_H 1
# define __need_FILE
# define __need___FILE
#endif /* Don't need FILE. */
#if !defined __FILE_defined && defined __need_FILE
struct _IO_FILE;
typedef struct _IO_FILE FILE;
#endif /* FILE not defined. */
#if !defined ____FILE_defined && defined __need___FILE
typedef struct _IO_FILE __FILE;
#endif /* __FILE not defined. */
#ifdef _STDIO_H
********* /usr/include/features.h *********
********* /usr/include/sys/cdefs.h *********
********* /usr/include/bits/wordsize.h *********
********* /usr/include/gnu/stubs.h *********
********* /usr/include/bits/wordsize.h *********
********* /usr/include/gnu/stubs-32.h *********
********* /usr/lib/gcc/i486-slackware-linux/4.2.4//include/stddef.h *********
#endif
#endif
********* /usr/include/bits/types.h *********
********* /usr/include/bits/wordsize.h *********
********* /usr/include/bits/typesizes.h *********
********* /usr/include/libio.h *********
#ifndef _IO_STDIO_H
#ifdef _G_NEED_STDARG_H
#endif
# else
struct _IO_jump_t; struct _IO_FILE;
# else
#else
typedef void _IO_lock_t;
#endif
struct _IO_marker {
struct _IO_marker *_next;
struct _IO_FILE *_sbuf;
int _pos;
};
enum __codecvt_result
{
__codecvt_ok,
__codecvt_partial,
__codecvt_error,
__codecvt_noconv
};
struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
#if 0
#else
int _flags2;
#endif
_IO_off_t _old_offset; /* This used to be _offset but it's too small. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001
_IO_off64_t _offset;
# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
# else
void *__pad1;
void *__pad2;
void *__pad3;
void *__pad4;
size_t __pad5;
# endif
int _mode;
char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
#endif
};
#endif /* _IO_STDIO_H */
********* /usr/include/_G_config.h *********
#ifndef _G_config_h
#define __need_mbstate_t
typedef struct
{
__off_t __pos;
__mbstate_t __state;
} _G_fpos_t;
typedef struct
{
__off64_t __pos;
__mbstate_t __state;
} _G_fpos64_t;
#define _G_off_t __off_t
#define _G_off64_t __off64_t
typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
#define _G_NEED_STDARG_H 1
#define _G_IO_IO_FILE_VERSION 0x20001
********* /usr/lib/gcc/i486-slackware-linux/4.2.4//include/stddef.h *********
#endif
#endif
#endif
#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */
#endif /* _STDDEF_H or __need_size_t. */
#endif
********* /usr/include/wchar.h *********
#ifndef _WCHAR_H
#if defined _WCHAR_H || defined __need_wint_t || !defined __WINT_TYPE__
# define __need_wint_t
#if (defined _WCHAR_H || defined __need_mbstate_t) && !defined __mbstate_t_defined
typedef struct
{
int __count;
union
{
# ifdef __WINT_TYPE__
__WINT_TYPE__ __wch;
# else
# endif
char __wchb[4];
} __value; /* Value so far. */
} __mbstate_t;
#endif
#endif /* ISO C99 or GCC and GNU. */
#endif /* GCC and use GNU. */
#endif /* Use ISO C95, C99 and Unix98. */
#endif
#endif
#endif /* _WCHAR_H defined */
#endif /* wchar.h */
********* /usr/lib/gcc/i486-slackware-linux/4.2.4//include/stddef.h *********
#endif
#endif
#endif
#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */
#endif /* _STDDEF_H or __need_size_t. */
#endif
#endif
#endif /* __WCHAR_T__ */
#endif /* __wchar_t__ */
#endif /* _STDDEF_H or __need_wchar_t. */
#if defined (__need_wint_t)
#ifndef _WINT_T
#ifndef __WINT_TYPE__
#define __WINT_TYPE__ unsigned int
#endif
typedef __WINT_TYPE__ wint_t;
#endif
#endif
#endif /* __sys_stdtypes_h */
********* /usr/lib/gcc/i486-slackware-linux/4.2.4//include/stdarg.h *********
#ifndef _STDARG_H
#ifndef _ANSI_STDARG_H_
#ifndef __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif
#else /* not __svr4__ || _SCO_DS */
#endif
#endif /* not _VA_LIST_, except on certain systems */
#endif /* not __svr4__ */
#endif /* _STDARG_H */
#endif /* not _ANSI_STDARG_H_ */
#endif /* not _STDARG_H */
********* /usr/include/bits/stdio_lim.h *********
********* /usr/include/bits/sys_errlist.h *********
>
> Chris
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
next prev parent reply other threads:[~2012-05-04 7:43 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-24 9:54 dependency tee from c parser entities downto token Konrad Eisele
2012-04-25 20:10 ` [PATCH] depend.c: build up a dependency tree from c entities downto tokens: entries in the tree are: macro-depend: tree of #if nesting macro-expansions: possible macro expansion source of a token tok->macro-expansions->macro tok->macro-depend->macro c entities are linked in via [stmt|expr|sym]->start-end-token Konrad Eisele
2012-04-30 22:58 ` dependency tee from c parser entities downto token Christopher Li
2012-05-02 7:27 ` Konrad Eisele
2012-05-03 23:52 ` Christopher Li
2012-05-04 7:33 ` Konrad Eisele [this message]
2012-05-04 9:25 ` Christopher Li
2012-05-04 10:36 ` Konrad Eisele
2012-05-04 12:36 ` Konrad Eisele
2012-05-04 15:30 ` Josh Triplett
2012-05-04 20:53 ` Konrad Eisele
2012-05-04 22:30 ` Christopher Li
2012-05-05 0:32 ` Josh Triplett
2012-05-05 8:59 ` Konrad Eisele
2012-05-05 8:56 ` Konrad Eisele
2012-05-04 18:02 ` Christopher Li
2012-05-04 21:46 ` Konrad Eisele
2012-05-04 21:56 ` Konrad Eisele
2012-05-04 23:05 ` Christopher Li
2012-05-05 8:54 ` Konrad Eisele
2012-05-05 11:12 ` Christopher Li
2012-05-05 16:59 ` Konrad Eisele
[not found] ` <CANeU7Qn7vUzLQAF6JGRECro_pPDnL7MCswkrNACe1wohLHZu7g@mail.gmail.com>
2012-05-05 19:56 ` Fwd: " Christopher Li
2012-05-05 23:38 ` Konrad Eisele
2012-05-06 18:34 ` Christopher Li
2012-05-07 6:12 ` Konrad Eisele
2012-05-07 22:06 ` Christopher Li
2012-05-08 6:38 ` Konrad Eisele
2012-05-09 9:18 ` Christopher Li
2012-05-09 9:48 ` Konrad Eisele
2012-05-09 22:50 ` Christopher Li
2012-05-10 6:19 ` Konrad Eisele
2012-05-10 6:38 ` Konrad Eisele
2012-05-10 9:37 ` Christopher Li
2012-05-10 9:51 ` Konrad Eisele
2012-05-10 11:25 ` Christopher Li
2012-05-10 12:14 ` Konrad Eisele
2012-05-10 12:28 ` Konrad Eisele
2012-05-11 19:40 ` Christopher Li
2012-05-11 21:48 ` Konrad Eisele
2012-05-12 11:02 ` Christopher Li
2012-05-12 17:46 ` Konrad Eisele
2012-05-12 17:57 ` Konrad Eisele
2012-05-13 8:52 ` Konrad Eisele
2012-05-15 6:30 ` Christopher Li
2012-05-15 7:52 ` Konrad Eisele
2012-05-15 9:44 ` Christopher Li
2012-05-15 13:03 ` Konrad Eisele
2012-05-14 10:53 ` Christopher Li
2012-05-10 9:03 ` Christopher Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FA38635.5060300@gaisler.com \
--to=konrad@gaisler.com \
--cc=eiselekd@gmail.com \
--cc=linux-sparse@vger.kernel.org \
--cc=sparse@chrisli.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).