diff options
author | Daniel Kraft <d@domob.eu> | 2008-08-28 20:03:02 +0200 |
---|---|---|
committer | Daniel Kraft <domob@gcc.gnu.org> | 2008-08-28 20:03:02 +0200 |
commit | 8e1f752a2627ad49b06825cb95d6a3520512f210 (patch) | |
tree | 40d33bd2a0404b05dfa1fbd4df6b97a4e144ac98 /gcc/fortran/primary.c | |
parent | cf7442bb5f155d6e7a1de5fe7922e7831ebefade (diff) | |
download | gcc-8e1f752a2627ad49b06825cb95d6a3520512f210.zip gcc-8e1f752a2627ad49b06825cb95d6a3520512f210.tar.gz gcc-8e1f752a2627ad49b06825cb95d6a3520512f210.tar.bz2 |
gfortran.h (enum expr_t): New value `EXPR_COMPCALL'.
2008-08-28 Daniel Kraft <d@domob.eu>
* gfortran.h (enum expr_t): New value `EXPR_COMPCALL'.
(gfc_get_typebound_proc): New macro.
(struct gfc_expr): New union-member `compcall' for EXPR_COMPCALL.
(enum gfc_exec_op): New value `EXEC_COMPCALL'.
(gfc_find_typebound_proc): New argument.
(gfc_copy_ref), (gfc_match_varspec): Made public.
* decl.c (match_procedure_in_type): Use gfc_get_typebound_proc.
* expr.c (free_expr0), (gfc_copy_expr): Handle EXPR_COMPCALL.
(gfc_copy_ref): Made public and use new name.
(simplify_const_ref): Use new name of gfc_copy_ref.
(simplify_parameter_variable): Ditto.
(gfc_simplify_expr): gcc_unreachable for EXPR_COMPCALL.
* match.c (match_typebound_call): New method.
(gfc_match_call): Allow for CALL's to typebound procedures.
* module.c (binding_passing), (binding_overriding): New variables.
(expr_types): Add EXPR_COMPCALL.
(mio_expr): gcc_unreachable for EXPR_COMPCALL.
(mio_typebound_proc), (mio_typebound_symtree): New methods.
(mio_f2k_derived): Handle type-bound procedures.
* primary.c (gfc_match_varspec): Made public and parse trailing
references to type-bound procedures; new argument `sub_flag'.
(gfc_match_rvalue): New name and argument of gfc_match_varspec.
(match_variable): Ditto.
* resolve.c (update_arglist_pass): New method.
(update_compcall_arglist), (resolve_typebound_static): New methods.
(resolve_typebound_call), (resolve_compcall): New methods.
(gfc_resolve_expr): Handle EXPR_COMPCALL.
(resolve_code): Handle EXEC_COMPCALL.
(resolve_fl_derived): New argument to gfc_find_typebound_proc.
(resolve_typebound_procedure): Ditto and removed not-implemented error.
* st.c (gfc_free_statement): Handle EXEC_COMPCALL.
* symbol.c (gfc_find_typebound_proc): New argument `noaccess' and
implement access-checking.
* trans-expr.c (gfc_apply_interface_mapping_to_expr): gcc_unreachable
on EXPR_COMPCALL.
* trans-intrinsic.c (gfc_conv_intrinsic_bound): Add missing break.
* trans-openmp.c (gfc_trans_omp_array_reduction): Add missing
intialization of ref->type.
2008-08-28 Daniel Kraft <d@domob.eu>
* gfortran.dg/typebound_call_1.f03: New test.
* gfortran.dg/typebound_call_2.f03: New test.
* gfortran.dg/typebound_call_3.f03: New test.
* gfortran.dg/typebound_call_4.f03: New test.
* gfortran.dg/typebound_call_5.f03: New test.
* gfortran.dg/typebound_call_6.f03: New test.
* gfortran.dg/typebound_proc_1.f08: Don't expect not-implemented error.
* gfortran.dg/typebound_proc_2.f90: Ditto.
* gfortran.dg/typebound_proc_5.f03: Ditto.
* gfortran.dg/typebound_proc_6.f03: Ditto.
* gfortran.dg/typebound_proc_7.f03: Ditto.
* gfortran.dg/typebound_proc_8.f03: Ditto.
From-SVN: r139724
Diffstat (limited to 'gcc/fortran/primary.c')
-rw-r--r-- | gcc/fortran/primary.c | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index 5d73407..c72f430 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -1676,7 +1676,7 @@ cleanup: } -/* Used by match_varspec() to extend the reference list by one +/* Used by gfc_match_varspec() to extend the reference list by one element. */ static gfc_ref * @@ -1699,15 +1699,17 @@ extend_ref (gfc_expr *primary, gfc_ref *tail) /* Match any additional specifications associated with the current variable like member references or substrings. If equiv_flag is set we only match stuff that is allowed inside an EQUIVALENCE - statement. */ + statement. sub_flag tells whether we expect a type-bound procedure found + to be a subroutine as part of CALL or a FUNCTION. */ -static match -match_varspec (gfc_expr *primary, int equiv_flag) +match +gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag) { char name[GFC_MAX_SYMBOL_LEN + 1]; gfc_ref *substring, *tail; gfc_component *component; gfc_symbol *sym = primary->symtree->n.sym; + gfc_symtree *tbp; match m; bool unknown; @@ -1751,12 +1753,60 @@ match_varspec (gfc_expr *primary, int equiv_flag) for (;;) { + gfc_try t; + m = gfc_match_name (name); if (m == MATCH_NO) gfc_error ("Expected structure component name at %C"); if (m != MATCH_YES) return MATCH_ERROR; + tbp = gfc_find_typebound_proc (sym, &t, name, false); + if (tbp) + { + gfc_symbol* tbp_sym; + + if (t == FAILURE) + return MATCH_ERROR; + + gcc_assert (!tail || !tail->next); + gcc_assert (primary->expr_type == EXPR_VARIABLE); + + tbp_sym = tbp->typebound->target->n.sym; + + primary->expr_type = EXPR_COMPCALL; + primary->value.compcall.tbp = tbp; + primary->ts = tbp_sym->ts; + + m = gfc_match_actual_arglist (tbp_sym->attr.subroutine, + &primary->value.compcall.actual); + if (m == MATCH_ERROR) + return MATCH_ERROR; + if (m == MATCH_NO) + { + if (sub_flag) + primary->value.compcall.actual = NULL; + else + { + gfc_error ("Expected argument list at %C"); + return MATCH_ERROR; + } + } + + if (sub_flag && !tbp_sym->attr.subroutine) + { + gfc_error ("'%s' at %C should be a SUBROUTINE", name); + return MATCH_ERROR; + } + if (!sub_flag && !tbp_sym->attr.function) + { + gfc_error ("'%s' at %C should be a FUNCTION", name); + return MATCH_ERROR; + } + + break; + } + component = gfc_find_component (sym, name, false, false); if (component == NULL) return MATCH_ERROR; @@ -2387,7 +2437,7 @@ gfc_match_rvalue (gfc_expr **result) e->expr_type = EXPR_VARIABLE; e->symtree = symtree; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); break; case FL_PARAMETER: @@ -2404,7 +2454,7 @@ gfc_match_rvalue (gfc_expr **result) } e->symtree = symtree; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); if (sym->ts.is_c_interop || sym->ts.is_iso_c) break; @@ -2461,7 +2511,7 @@ gfc_match_rvalue (gfc_expr **result) e = gfc_get_expr (); e->expr_type = EXPR_VARIABLE; e->symtree = symtree; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); break; } @@ -2488,7 +2538,7 @@ gfc_match_rvalue (gfc_expr **result) e->symtree = symtree; e->expr_type = EXPR_VARIABLE; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); break; } @@ -2584,7 +2634,7 @@ gfc_match_rvalue (gfc_expr **result) e = gfc_get_expr (); e->symtree = symtree; e->expr_type = EXPR_VARIABLE; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); break; } @@ -2607,9 +2657,9 @@ gfc_match_rvalue (gfc_expr **result) break; } - /*FIXME:??? match_varspec does set this for us: */ + /*FIXME:??? gfc_match_varspec does set this for us: */ e->ts = sym->ts; - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); break; } @@ -2698,7 +2748,7 @@ gfc_match_rvalue (gfc_expr **result) /* If our new function returns a character, array or structure type, it might have subsequent references. */ - m = match_varspec (e, 0); + m = gfc_match_varspec (e, 0, false); if (m == MATCH_NO) m = MATCH_YES; @@ -2882,7 +2932,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag) expr->where = where; /* Now see if we have to do more. */ - m = match_varspec (expr, equiv_flag); + m = gfc_match_varspec (expr, equiv_flag, false); if (m != MATCH_YES) { gfc_free_expr (expr); |