Mercurial > cospy
changeset 6:165781cb4cdd
Parase pointers and const type
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 08 Sep 2010 21:29:30 +0800 |
parents | a32f4bd19eda |
children | 7fec19e27411 |
files | src/Makefile src/cospy.c src/test.c |
diffstat | 3 files changed, 79 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Makefile Wed Sep 08 17:54:33 2010 +0800 +++ b/src/Makefile Wed Sep 08 21:29:30 2010 +0800 @@ -9,7 +9,7 @@ cospy.so: $(PLUGIN_OBJECT_FILES) $(GCC) -shared $^ -o $@ -test: +test: cospy.so $(GCC) -fplugin=`pwd`/cospy.so $(CFLAGS) -c test.c clean:
--- a/src/cospy.c Wed Sep 08 17:54:33 2010 +0800 +++ b/src/cospy.c Wed Sep 08 21:29:30 2010 +0800 @@ -10,15 +10,92 @@ int plugin_is_GPL_compatible; +static char * +parse_type(tree type_node) { + tree type_v; + tree *pointers; + tree type_decl, type_name; + int lvl = 0; + int const_cnt = 0; + char *type_str; + const char *base_type_name; + int type_str_len; + int i, ptr_i; + + type_v = type_node; + while(TREE_CODE(type_v) == POINTER_TYPE) { + if(TREE_READONLY(type_v)) + const_cnt++; + type_v = TREE_TYPE(type_v); + lvl++; + } + + type_decl = TYPE_NAME(type_v); + type_name = DECL_NAME(type_decl); + base_type_name = IDENTIFIER_POINTER(type_name); + + type_str_len = lvl + strlen(base_type_name) + const_cnt * 5; /* "const" */ + if(TREE_READONLY(type_v)) + type_str_len += 6; /* "const " */ + type_str = (char *)ggc_alloc(type_str_len + 1); + + type_str[0] = 0; + if(TREE_READONLY(type_v)) + strcpy(type_str, "const "); + + strcat(type_str, base_type_name); + + pointers = (tree *)ggc_alloc(sizeof(tree) * lvl); + type_v = type_node; + for(ptr_i = 0; ptr_i < lvl; ptr_i++) { + pointers[ptr_i] = type_v; + type_v = TREE_TYPE(type_v); + } + + i = strlen(type_str); + for(ptr_i = lvl - 1; ptr_i >= 0; ptr_i--) { + type_v = pointers[ptr_i]; + type_str[i++] = '*'; + if(TREE_READONLY(type_v)) { + type_str[i] = 0; + strcat(type_str, "const"); + i += 5; + } + } + type_str[i] = 0; + + ggc_free(pointers); + + return type_str; +} + static void handle_all_passes(void *gcc_data, void *user_data) { tree decl; + tree fntype; + tree arg, arg_name; + tree arg_type; + char *arg_type_str; + function_args_iterator itr; decl = cfun->decl; + printf("decl %x\n", decl); printf(" %s:%d:%s\n", current_function_name(), DECL_SOURCE_LINE(decl), DECL_SOURCE_FILE(decl)); + + arg = DECL_ARGUMENTS(decl); + while(arg) { + arg_name = DECL_NAME(arg); + arg_type = TREE_TYPE(arg); + arg_type_str = parse_type(arg_type); + printf(" %s:%s\n", + IDENTIFIER_POINTER(arg_name), + arg_type_str); + ggc_free(arg_type_str); + arg = TREE_CHAIN(arg); + } } int