aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2008-07-29 20:44:09 +0000
committerPaul Thomas <pault@gcc.gnu.org>2008-07-29 20:44:09 +0000
commit7d1f1e6144bab4e9e2fadc324c5213b415efb952 (patch)
tree1d8aa1d99f6217a1f9fdc2522ae987cc7d2f9586 /gcc/fortran/trans-expr.c
parente54cf1573e36c71c5277d59fd1c1915984b06432 (diff)
downloadgcc-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.c41
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;