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
--- a/src/test.c	Wed Sep 08 17:54:33 2010 +0800
+++ b/src/test.c	Wed Sep 08 21:29:30 2010 +0800
@@ -5,7 +5,7 @@
 }
 
 int
-main(int argc, const char *argv[]) {
+main(int argc, const char * const argv[]) {
     printf("test %d\n", value(12));
     return 0;
 }