Re: [Generic] change the value of an attribute

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/26/2011 05:08 PM, charfi asma wrote:
Hello every body,

I have a class named MyClass, that has an operation (MyOperation1) and this
operation change the value of MyAttribute1 of type Integer.

to call my operation in the main I added a hidden argument (this)

main
{

     tree myClass_type = make_node(RECORD_TYPE);
     TYPE_PACKED(myClass_type) = false;
     TYPE_NAME(myClass_type) = get_identifier("MyClass");

//properties:

     tree myAttribute1_type = integer_type_node;
     tree myAttribute1_tree = build_decl(BUILTINS_LOCATION, FIELD_DECL,
get_identifier("MyAttribute1"), myAttribute1_type);
     DECL_CONTEXT(myAttribute1_tree) = myClass_type;
     DECL_PACKED(myAttribute1_tree) = false;
     TYPE_FIELDS(myClass_type) = myAttribute1_tree;

//operations:

     tree myOperation2_type = build_function_type_list(void_type_node,
NULL_TREE);

     tree myOperation2_decl = build_decl(BUILTINS_LOCATION, FUNCTION_DECL,
get_identifier("MyOperation2"), myOperation2_type);
     tree myOperation2_tree = create_operation(myClass_type, myOperation2_decl);
// find bellow

     DECL_CONTEXT(myOperation2_tree) = myClass_type;
     DECL_PACKED(myOperation2_tree) = false;
     TYPE_METHODS(myClass_type) =  myOperation2_tree;

     layout_type(myClass_type);
     rest_of_type_compilation(myClass_type, 1);

// create instance

     tree x_tree = build_decl(BUILTINS_LOCATION, VAR_DECL, get_identifier("x"),
myClass_type);
     TREE_STATIC(x_tree) = false;
     TREE_PUBLIC(x_tree) = true;
     DECL_CONTEXT(x_tree) = main_fn_decl;
     TREE_USED(x_tree) = true;

     append_to_statement_list(x_tree,&main_stmts);
     layout_decl(x_tree, false);
     rest_of_decl_compilation(x_tree, 1, 0);
     VEC_safe_push( tree, gc, global_decls_vec, x_tree );

// call operation

     tree target_ptr = build1(ADDR_EXPR,
build_pointer_type(TREE_TYPE(x_tree)),x_tree); //&x

     tree call_myOperation2 = build_call_expr(myOperation2_tree, 1,  target_ptr);
     append_to_statement_list(call_myOperation2,&main_stmts);

...
}

Now, I want to modify the value of MyAttribute1 in the operation body. (
this.MyAttribute1=10)

tree create_operation(tree class_t, tree operation )
{


// set argument manually

tree __func_param = NULL_TREE;
tree parm_type = build_pointer_type(class_t);
tree parm = build_decl (BUILTINS_LOCATION, PARM_DECL, get_identifier("this"),
parm_type);
TREE_CONSTANT (parm) = true;
TREE_READONLY (parm) = true;


DECL_CHAIN (parm) = __func_param;
__func_param = parm;
DECL_ARGUMENTS(operation)=(__func_param);


// return type preparation
tree __func_result = build_decl(BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
TREE_TYPE(operation));
DECL_CONTEXT(__func_result) = operation;
DECL_ARTIFICIAL(__func_result) = true;
DECL_IGNORED_P(__func_result) = true;
DECL_RESULT(operation) = __func_result;

// debug tree needed for bind exp
tree __func_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
DECL_INITIAL(operation) = __func_art_block;

tree func_stmts = alloc_stmt_list ();

//set the body


     tree t = TREE_TYPE(TREE_TYPE(parm));

     tree ref = build1 (INDIRECT_REF, t, parm);

     tree __struct_field0 = TYPE_FIELDS(TREE_TYPE(ref));

     tree __struct_access_0 = build3(COMPONENT_REF, TREE_TYPE(__struct_field0),
ref, __struct_field0, NULL_TREE);

     tree modify_att_tree = build2(MODIFY_EXPR, TREE_TYPE(__struct_field0),
__struct_access_0, build_int_cst(integer_type_node, 10));

append_to_statement_list(modify_att_tree,&func_stmts);

/********************************add the final return statement
*********************************/

   tree func_ret_expr = build1(RETURN_EXPR, void_type_node, NULL_TREE);

append_to_statement_list(func_ret_expr,&func_stmts);


// bind and gimplification
DECL_SAVED_TREE(operation) = build3(BIND_EXPR, void_type_node, NULL_TREE,
func_stmts, __func_art_block);

// pass to middle end
gimplify_function_tree(operation);
cgraph_node(operation);
cgraph_finalize_function(operation,false);

return operation;

}

I get error while calling gimplify_function_tree(operation); it comes from
COMPONENT_REF gimplification (call to gimplify_compound_lval)

this is the debug output:

(gdb) n
7771      bind = gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
size_binop_loc (loc=0, code=EXACT_DIV_EXPR, arg0=0x0, arg1=0xb7572680)
     at ../../gcc-dev/gcc/fold-const.c:1414
1414      tree type = TREE_TYPE (arg0);


any idea ?

thank you in advance

Asma
Hey Asma,

the problem in your code is that you access the class/record in create_operation() by a COMPONENT_REF although the class/record's layout hasn't yet been built. To be clear, you call layout_type() which for example sets the offset for each FIELD_DECL after create_operation(). Though, when the gimplifier tries to access the record, it requires the offset of the FIELD_DECL to be available, but in your case, it is NULL_TREE.

Since layout_type() for RECORD_TYPES doesn't work on TYPE_METHODS, you could call layout_type() before processing the operations. By the way

DECL_PACKED(myOperation2_tree) = false;

does not work for FUNCTION_DECL, but only for FIELD_DECLs.

Andi



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux