summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
authorjanus <janus@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-02 19:53:37 +0000
committerjanus <janus@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-02 19:53:37 +0000
commitcad0ddcfd966a705b9d1eeaa77d5e73d20939068 (patch)
tree22cdfa5a0f9753aaa861e0696994a9d143ec1e49 /gcc/fortran/trans-decl.c
parent35c0d62d8355ad4715f632e777a4259d223dc023 (diff)
downloadgcc-cad0ddcfd966a705b9d1eeaa77d5e73d20939068.tar.gz
2008-07-02 Janus Weil <janus@gcc.gnu.org>
Tobias Burnus <burnus@net-b.de> Paul Thomas <pault@gcc.gnu.org> PR fortran/32580 * gfortran.h (struct gfc_symbol): New member "proc_pointer". * check.c (gfc_check_associated,gfc_check_null): Implement procedure pointers. * decl.c (match_procedure_decl): Ditto. * expr.c (gfc_check_pointer_assign,gfc_check_assign_symbol): Ditto. * interface.c (compare_actual_formal): Ditto. * match.h: Ditto. * match.c (gfc_match_pointer_assignment): Ditto. * parse.c (parse_interface): Ditto. * primary.c (gfc_match_rvalue,match_variable): Ditto. * resolve.c (resolve_fl_procedure): Ditto. * symbol.c (check_conflict,gfc_add_external,gfc_add_pointer, gfc_copy_attr,gen_fptr_param,build_formal_args): Ditto. * trans-decl.c (get_proc_pointer_decl,gfc_get_extern_function_decl, create_function_arglist): Ditto. * trans-expr.c (gfc_conv_variable,gfc_conv_function_val, gfc_conv_function_call,gfc_trans_pointer_assignment): Ditto. 2008-07-02 Janus Weil <janus@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> PR fortran/32580 * gfortran.dg/c_f_pointer_tests_3.f90: Updated. * gfortran.dg/proc_decl_1.f90: Updated. * gfortran.dg/proc_ptr_1.f90: New. * gfortran.dg/proc_ptr_2.f90: New. * gfortran.dg/proc_ptr_3.f90: New. * gfortran.dg/proc_ptr_4.f90: New. * gfortran.dg/proc_ptr_5.f90: New. * gfortran.dg/proc_ptr_6.f90: New. * gfortran.dg/proc_ptr_7.f90: New. * gfortran.dg/proc_ptr_8.f90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@137386 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 686e059ec4e..e960fa026b1 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1104,6 +1104,44 @@ gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
}
+/* Declare a procedure pointer. */
+
+static tree
+get_proc_pointer_decl (gfc_symbol *sym)
+{
+ tree decl;
+
+ decl = sym->backend_decl;
+ if (decl)
+ return decl;
+
+ decl = build_decl (VAR_DECL, get_identifier (sym->name),
+ build_pointer_type (gfc_get_function_type (sym)));
+
+ if (sym->ns->proc_name->backend_decl == current_function_decl
+ || sym->attr.contained)
+ gfc_add_decl_to_function (decl);
+ else
+ gfc_add_decl_to_parent_function (decl);
+
+ sym->backend_decl = decl;
+
+ if (!sym->attr.use_assoc
+ && (sym->attr.save != SAVE_NONE || sym->attr.data
+ || (sym->value && sym->ns->proc_name->attr.is_main_program)))
+ TREE_STATIC (decl) = 1;
+
+ if (TREE_STATIC (decl) && sym->value)
+ {
+ /* Add static initializer. */
+ DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
+ TREE_TYPE (decl), sym->attr.dimension, sym->attr.proc_pointer);
+ }
+
+ return decl;
+}
+
+
/* Get a basic decl for an external function. */
tree
@@ -1126,6 +1164,9 @@ gfc_get_extern_function_decl (gfc_symbol * sym)
to know that. */
gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
+ if (sym->attr.proc_pointer)
+ return get_proc_pointer_decl (sym);
+
if (sym->attr.intrinsic)
{
/* Call the resolution function to get the actual name. This is
@@ -1540,6 +1581,9 @@ create_function_arglist (gfc_symbol * sym)
type = gfc_sym_type (f->sym);
}
+ if (f->sym->attr.proc_pointer)
+ type = build_pointer_type (type);
+
/* Build a the argument declaration. */
parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type);