diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2009-10-05 18:19:55 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2009-10-05 18:19:55 +0000 |
commit | 7cf078dceaaf3fac20ae6cad5077f9cec6256c8f (patch) | |
tree | dcef12f6299ca2279a3958f860cb3333621196ed /gcc/fortran/module.c | |
parent | e48efd3b2b9cb628b41e8d0e09eac19a66e90ad2 (diff) | |
download | gcc-7cf078dceaaf3fac20ae6cad5077f9cec6256c8f.zip gcc-7cf078dceaaf3fac20ae6cad5077f9cec6256c8f.tar.gz gcc-7cf078dceaaf3fac20ae6cad5077f9cec6256c8f.tar.bz2 |
trans-expr.c (select_class_proc): New function.
2009-10-05 Paul Thomas <pault@gcc.gnu.org>
* trans-expr.c (select_class_proc): New function.
(conv_function_val): Deal with class methods and call above.
* symbol.c (gfc_type_compatible): Treat case where both ts1 and
ts2 are BT_CLASS.
gfortran.h : Add structure gfc_class_esym_list and include in
the structure gfc_expr.
* module.c (load_derived_extensions): New function.
(read_module): Call above.
(write_dt_extensions): New function.
(write_derived_extensions): New function.
(write_module): Use the above.
* resolve.c (resolve_typebound_call): Add a function expression
for class methods. This carries the chain of symbols for the
dynamic dispatch in select_class_proc.
(resolve_compcall): Add second, boolean argument to indicate if
a function is being handled.
(check_members): New function.
(check_class_members): New function.
(resolve_class_compcall): New function.
(resolve_class_typebound_call): New function.
(gfc_resolve_expr): Call above for component calls..
2009-10-05 Paul Thomas <pault@gcc.gnu.org>
* gfortran.dg/dynamic_dispatch_1.f90: New test.
* gfortran.dg/dynamic_dispatch_2.f90: New test.
* gfortran.dg/dynamic_dispatch_3.f90: New test.
* gfortran.dg/module_md5_1.f90: Update md5 sum.
From-SVN: r152463
Diffstat (limited to 'gcc/fortran/module.c')
-rw-r--r-- | gcc/fortran/module.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 1769ead..2112d3e 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -3972,6 +3972,61 @@ load_equiv (void) } +/* This function loads the sym_root of f2k_derived with the extensions to + the derived type. */ +static void +load_derived_extensions (void) +{ + int symbol, nuse, j; + gfc_symbol *derived; + gfc_symbol *dt; + gfc_symtree *st; + pointer_info *info; + char name[GFC_MAX_SYMBOL_LEN + 1]; + char module[GFC_MAX_SYMBOL_LEN + 1]; + const char *p; + + mio_lparen (); + while (peek_atom () != ATOM_RPAREN) + { + mio_lparen (); + mio_integer (&symbol); + info = get_integer (symbol); + derived = info->u.rsym.sym; + + gcc_assert (derived->attr.flavor == FL_DERIVED); + if (derived->f2k_derived == NULL) + derived->f2k_derived = gfc_get_namespace (NULL, 0); + + while (peek_atom () != ATOM_RPAREN) + { + mio_lparen (); + mio_internal_string (name); + mio_internal_string (module); + + /* Only use one use name to find the symbol. */ + nuse = number_use_names (name, false); + j = 1; + p = find_use_name_n (name, &j, false); + st = gfc_find_symtree (gfc_current_ns->sym_root, p); + dt = st->n.sym; + st = gfc_find_symtree (derived->f2k_derived->sym_root, name); + if (st == NULL) + { + /* Only use the real name in f2k_derived to ensure a single + symtree. */ + st = gfc_new_symtree (&derived->f2k_derived->sym_root, name); + st->n.sym = dt; + st->n.sym->refs++; + } + mio_rparen (); + } + mio_rparen (); + } + mio_rparen (); +} + + /* Recursive function to traverse the pointer_info tree and load a needed symbol. We return nonzero if we load a symbol and stop the traversal, because the act of loading can alter the tree. */ @@ -4113,7 +4168,7 @@ check_for_ambiguous (gfc_symbol *st_sym, pointer_info *info) static void read_module (void) { - module_locus operator_interfaces, user_operators; + module_locus operator_interfaces, user_operators, extensions; const char *p; char name[GFC_MAX_SYMBOL_LEN + 1]; int i; @@ -4130,10 +4185,13 @@ read_module (void) skip_list (); skip_list (); - /* Skip commons and equivalences for now. */ + /* Skip commons, equivalences and derived type extensions for now. */ skip_list (); skip_list (); + get_module_locus (&extensions); + skip_list (); + mio_lparen (); /* Create the fixup nodes for all the symbols. */ @@ -4386,6 +4444,11 @@ read_module (void) gfc_check_interfaces (gfc_current_ns); + /* Now we should be in a position to fill f2k_derived with derived type + extensions, since everything has been loaded. */ + set_module_locus (&extensions); + load_derived_extensions (); + /* Clean up symbol nodes that were never loaded, create references to hidden symbols. */ @@ -4594,6 +4657,36 @@ write_equiv (void) } +/* Write derived type extensions to the module. */ + +static void +write_dt_extensions (gfc_symtree *st) +{ + mio_lparen (); + mio_pool_string (&st->n.sym->name); + if (st->n.sym->module != NULL) + mio_pool_string (&st->n.sym->module); + else + mio_internal_string (module_name); + mio_rparen (); +} + +static void +write_derived_extensions (gfc_symtree *st) +{ + if (!((st->n.sym->attr.flavor == FL_DERIVED) + && (st->n.sym->f2k_derived != NULL) + && (st->n.sym->f2k_derived->sym_root != NULL))) + return; + + mio_lparen (); + mio_symbol_ref (&(st->n.sym)); + gfc_traverse_symtree (st->n.sym->f2k_derived->sym_root, + write_dt_extensions); + mio_rparen (); +} + + /* Write a symbol to the module. */ static void @@ -4820,6 +4913,13 @@ write_module (void) write_char ('\n'); write_char ('\n'); + mio_lparen (); + gfc_traverse_symtree (gfc_current_ns->sym_root, + write_derived_extensions); + mio_rparen (); + write_char ('\n'); + write_char ('\n'); + /* Write symbol information. First we traverse all symbols in the primary namespace, writing those that need to be written. Sometimes writing one symbol will cause another to need to be |