Christopher Li wrote:
On Wed, May 2, 2012 at 12:27 AM, Konrad Eisele<eiselekd@xxxxxxxxx> 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@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html