diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2008-07-29 20:44:09 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2008-07-29 20:44:09 +0000 |
commit | 7d1f1e6144bab4e9e2fadc324c5213b415efb952 (patch) | |
tree | 1d8aa1d99f6217a1f9fdc2522ae987cc7d2f9586 /gcc/fortran/trans-expr.c | |
parent | e54cf1573e36c71c5277d59fd1c1915984b06432 (diff) | |
download | gcc-7d1f1e6144bab4e9e2fadc324c5213b415efb952.zip gcc-7d1f1e6144bab4e9e2fadc324c5213b415efb952.tar.gz gcc-7d1f1e6144bab4e9e2fadc324c5213b415efb952.tar.bz2 |
trans-expr.c (conv_parent_component_references): New function to build missing parent references.
2008-07-29 Paul Thomas <pault@gcc.gnu.org>
fortran/
* trans-expr.c (conv_parent_component_references): New function
to build missing parent references.
(gfc_conv_variable): Call it
* symbol.c (gfc_add_component): Check that component name in a
derived type extension does not appear in parent.
(gfc_find_component): For a derived type extension, check if
the component appears in the parent derived type by calling
self. Separate errors for private components and private types.
* decl.c (match_data_constant): Add extra arg to call to
gfc_match_structure_constructor.
(check_extended_derived_type): New function to check that a
parent derived type exists and that it is OK for exension.
(gfc_get_type_attr_spec): Add extra argument 'name' and return
it if extends is specified.
(gfc_match_derived_decl): Match derived type extension and
build a first component of the parent derived type if OK. Add
the f2k namespace if not present.
* gfortran.h : Add the extension attribute.
* module.c : Handle attribute 'extension'.
* match.h : Modify prototypes for gfc_get_type_attr_spec and
gfc_match_structure_constructor.
* primary.c (build_actual_constructor): New function extracted
from gfc_match_structure_constructor and modified to call self
iteratively to build derived type extensions, when f2k named
components are used.
(gfc_match_structure_constructor): Do not throw error for too
many components if a parent type is being handled. Use
gfc_find_component to generate errors for non-existent or
private components. Iteratively call self for derived type
extensions so that parent constructor is built. If extension
and components left over, throw error.
(gfc_match_rvalue): Add extra arg to call to
gfc_match_structure_constructor.
* trans-array.c (gfc_conv_resolve_dependencies): If lhs and rhs
are the same symbol, aliassing does not matter.
testsuite/
* gfortran.dg/extends_1.f03: New test.
* gfortran.dg/extends_2.f03: New test.
* gfortran.dg/extends_3.f03: New test.
* gfortran.dg/extends_4.f03: New test.
* gfortran.dg/extends_5.f03: New test.
* gfortran.dg/extends_6.f03: New test.
* gfortran.dg/private_type_6.f90: Modify error message.
* gfortran.dg/structure_constructor_7.f03: Modify error message.
* gfortran.dg/structure_constructor_8.f03: Modify error message.
From-SVN: r138275
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r-- | gcc/fortran/trans-expr.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 05ee390..94b912f 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1,6 +1,6 @@ /* Expression translation - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. Contributed by Paul Brook <paul@nowt.org> and Steven Bosscher <s.bosscher@student.tudelft.nl> @@ -395,6 +395,40 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref) } +/* This function deals with component references to components of the + parent type for derived type extensons. */ +static void +conv_parent_component_references (gfc_se * se, gfc_ref * ref) +{ + gfc_component *c; + gfc_component *cmp; + gfc_symbol *dt; + gfc_ref parent; + + dt = ref->u.c.sym; + c = ref->u.c.component; + + /* Build a gfc_ref to recursively call gfc_conv_component_ref. */ + parent.type = REF_COMPONENT; + parent.next = NULL; + parent.u.c.sym = dt; + parent.u.c.component = dt->components; + + if (dt->attr.extension && dt->components) + { + /* Return if the component is not in the parent type. */ + for (cmp = dt->components->next; cmp; cmp = cmp->next) + if (strcmp (c->name, cmp->name) == 0) + return; + + /* Otherwise build the reference and call self. */ + gfc_conv_component_ref (se, &parent); + parent.u.c.sym = dt->components->ts.derived; + parent.u.c.component = c; + conv_parent_component_references (se, &parent); + } +} + /* Return the contents of a variable. Also handles reference/pointer variables (all Fortran pointer references are implicit). */ @@ -561,6 +595,9 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) break; case REF_COMPONENT: + if (ref->u.c.sym->attr.extension) + conv_parent_component_references (se, ref); + gfc_conv_component_ref (se, ref); break; |