diff options
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r-- | gcc/fortran/trans-decl.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 686e059..e960fa0 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); |