diff options
author | Julian Brown <julian@codesourcery.com> | 2019-12-20 01:39:49 +0000 |
---|---|---|
committer | Julian Brown <jules@gcc.gnu.org> | 2019-12-20 01:39:49 +0000 |
commit | 9be3ac5d63f0f0d79d220bb3a10842b28a1e48ad (patch) | |
tree | c4426113e90ebe5b42363af5610987218e468d1b /gcc/fortran/trans-openmp.c | |
parent | 02817027ca02f32cfd4fbaa71edf879a024089a3 (diff) | |
download | gcc-9be3ac5d63f0f0d79d220bb3a10842b28a1e48ad.zip gcc-9be3ac5d63f0f0d79d220bb3a10842b28a1e48ad.tar.gz gcc-9be3ac5d63f0f0d79d220bb3a10842b28a1e48ad.tar.bz2 |
Fortran polymorphic class-type support for OpenACC
gcc/fortran/
* openmp.c (resolve_oacc_data_clauses): Don't disallow allocatable
polymorphic types for OpenACC.
* trans-openmp.c (gfc_trans_omp_clauses): Support polymorphic class
types.
libgomp/
* testsuite/libgomp.oacc-fortran/class-ptr-param.f95: New test.
* testsuite/libgomp.oacc-fortran/classtypes-1.f95: New test.
* testsuite/libgomp.oacc-fortran/classtypes-2.f95: New test.
From-SVN: r279631
Diffstat (limited to 'gcc/fortran/trans-openmp.c')
-rw-r--r-- | gcc/fortran/trans-openmp.c | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index c9f4bd2..f1e6e87 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -2471,14 +2471,42 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, tree present = (gfc_omp_is_optional_argument (decl) ? gfc_omp_check_optional_argument (decl, true) : NULL_TREE); - if (POINTER_TYPE_P (TREE_TYPE (decl)) - && (gfc_omp_privatize_by_reference (decl) - || GFC_DECL_GET_SCALAR_POINTER (decl) - || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) - || GFC_DECL_CRAY_POINTEE (decl) - || GFC_DESCRIPTOR_TYPE_P - (TREE_TYPE (TREE_TYPE (decl))) - || n->sym->ts.type == BT_DERIVED)) + if (n->sym->ts.type == BT_CLASS) + { + tree type = TREE_TYPE (decl); + if (n->sym->attr.optional) + sorry ("optional class parameter"); + if (POINTER_TYPE_P (type)) + { + node4 = build_omp_clause (input_location, + OMP_CLAUSE_MAP); + OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER); + OMP_CLAUSE_DECL (node4) = decl; + OMP_CLAUSE_SIZE (node4) = size_int (0); + decl = build_fold_indirect_ref (decl); + } + tree ptr = gfc_class_data_get (decl); + ptr = build_fold_indirect_ref (ptr); + OMP_CLAUSE_DECL (node) = ptr; + OMP_CLAUSE_SIZE (node) = gfc_class_vtab_size_get (decl); + node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP); + OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET); + OMP_CLAUSE_DECL (node2) = decl; + OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type); + node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP); + OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH_DETACH); + OMP_CLAUSE_DECL (node3) = gfc_class_data_get (decl); + OMP_CLAUSE_SIZE (node3) = size_int (0); + goto finalize_map_clause; + } + else if (POINTER_TYPE_P (TREE_TYPE (decl)) + && (gfc_omp_privatize_by_reference (decl) + || GFC_DECL_GET_SCALAR_POINTER (decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) + || GFC_DECL_CRAY_POINTEE (decl) + || GFC_DESCRIPTOR_TYPE_P + (TREE_TYPE (TREE_TYPE (decl))) + || n->sym->ts.type == BT_DERIVED)) { tree orig_decl = decl; node4 = build_omp_clause (input_location, @@ -2645,11 +2673,15 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, symbol_attribute sym_attr; - sym_attr = lastcomp->u.c.component->attr; + if (lastcomp->u.c.component->ts.type == BT_CLASS) + sym_attr = CLASS_DATA (lastcomp->u.c.component)->attr; + else + sym_attr = lastcomp->u.c.component->attr; gfc_init_se (&se, NULL); if (!sym_attr.dimension + && lastcomp->u.c.component->ts.type != BT_CLASS && lastcomp->u.c.component->ts.type != BT_DERIVED) { /* Last component is a scalar. */ @@ -2679,13 +2711,24 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, tree inner = se.expr; - /* Last component is a derived type. */ - if (lastcomp->u.c.component->ts.type == BT_DERIVED) + /* Last component is a derived type or class pointer. */ + if (lastcomp->u.c.component->ts.type == BT_DERIVED + || lastcomp->u.c.component->ts.type == BT_CLASS) { if (sym_attr.allocatable || sym_attr.pointer) { - tree data = inner; - tree size = TYPE_SIZE_UNIT (TREE_TYPE (inner)); + tree data, size; + + if (lastcomp->u.c.component->ts.type == BT_CLASS) + { + data = gfc_class_data_get (inner); + size = gfc_class_vtab_size_get (inner); + } + else /* BT_DERIVED. */ + { + data = inner; + size = TYPE_SIZE_UNIT (TREE_TYPE (inner)); + } OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (data); |