view src/cospy.c @ 7:7fec19e27411

Add more comment
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 08 Sep 2010 21:35:16 +0800
parents 165781cb4cdd
children 5502f175d348
line wrap: on
line source

#include "gcc-plugin.h"
#include "plugin-version.h"
#include "system.h"
#include "coretypes.h"
#include "tree-pass.h"
#include "tree.h"
#include "gimple.h"
#include "cgraph.h"
#include <stdio.h>

int plugin_is_GPL_compatible;

/*! \brief Parse a tree of type and return respective string.
 *
 * \return a string for the type.  It must be free through ggc_free().
 */
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;
    
    /* Collect pointers */
    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++;
    }

    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);
    }

    /* Get name of base type */
    type_decl = TYPE_NAME(type_v);
    type_name = DECL_NAME(type_decl);
    base_type_name = IDENTIFIER_POINTER(type_name);
    
    /* Compute total length of string of full type */
    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);
    
    /* modify const for base type */
    type_str[0] = 0;
    if(TREE_READONLY(type_v))
	strcpy(type_str, "const ");
    strcat(type_str, base_type_name);
    
    /* Add pointers and const modifications after base type */
    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
plugin_init(struct plugin_name_args *plugin_info,
	    struct plugin_gcc_version *version) {
    struct cgraph_node_hook_list *hook;
    
    if (!plugin_default_version_check (version, &gcc_version))
	return 1;
    printf("Initialize plugin %s\n", plugin_info->base_name);

    register_callback(plugin_info->base_name, PLUGIN_ALL_PASSES_START,
		      handle_all_passes, NULL);
    return 0;
}