This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

How to insert a new function in plugin?


Hi,

I want to insert a new function `test_fn` in plugin and call it in `main`,
but got `undefined reference to `test_fn’ in `ld`.  Can someone please give
any help? Thanks.

Here is the example code,

//====================== plugin.c

#include "gcc-plugin.h"
#include "plugin-version.h"
#include "tree.h"
#include "tree-iterator.h"
#include "toplev.h"
#include "c-family/c-common.h"
#include "cgraph.h"
#include "langhooks.h"

int plugin_is_GPL_compatible = 1;

// this example is from gcc/function-tests.c. The built function is
//
//      int test_fn (void) { return 42; }
//
static tree build_fn() {
 // build function fndecl
 auto_vec<tree> param_types;
 tree fn_type = build_function_type_array(
     integer_type_node, param_types.length(), param_types.address());
 tree fndecl = build_fn_decl("test_fn", fn_type);
 TREE_PUBLIC(fndecl) = 1;

 tree retval =
     build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
integer_type_node);
 DECL_ARTIFICIAL(retval) = 1;
 DECL_IGNORED_P(retval) = 1;
 DECL_RESULT(fndecl) = retval;
 DECL_CONTEXT(retval) = fndecl;
 tree stmt_list = alloc_stmt_list();
 tree_stmt_iterator stmt_iter = tsi_start(stmt_list);
 tree block = make_node(BLOCK);
 tree bind_expr = build3(BIND_EXPR, void_type_node, NULL, stmt_list, block);
 tree modify_retval = build2(MODIFY_EXPR, integer_type_node, retval,
                             build_int_cst(integer_type_node, 42));
 tree return_stmt = build1(RETURN_EXPR, integer_type_node, modify_retval);
 tsi_link_after(&stmt_iter, return_stmt, TSI_CONTINUE_LINKING);
 DECL_INITIAL(fndecl) = block;
 BLOCK_SUPERCONTEXT(block) = fndecl;
 DECL_SAVED_TREE(fndecl) = bind_expr;
 BLOCK_VARS(block) = BIND_EXPR_VARS(bind_expr);

 // But how to deal with this function?
 allocate_struct_function(fndecl, false);
 announce_function(fndecl);
 c_determine_visibility(fndecl);
 c_genericize(fndecl);
 cgraph_node::finalize_function(fndecl, true);

 return fndecl;
}

void on_start_parse_function(void *gcc_data, void *user_data) {
   build_fn();
}

int plugin_init(struct plugin_name_args *plugin_info,
               struct plugin_gcc_version *version) {
 if (!plugin_default_version_check(version, &gcc_version)) {
   return 1;
 }

 register_callback(NULL, PLUGIN_START_PARSE_FUNCTION,
on_start_parse_function,
                   NULL);
 return 0;
}

// =================== main.c

int main() {
   test_fn();  // error: `undefined reference to `test_fn’` in ld
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]