From: Bernhard Reutner-Fischer <al...@gcc.gnu.org>

Introduce a helper to construct a user operator from a name and the
reverse operation, i.e. a helper to construct a name from a user
operator.

Cc: Jakub Jelinek <ja...@redhat.com>

gcc/fortran/ChangeLog:

2017-10-29  Bernhard Reutner-Fischer  <al...@gcc.gnu.org>

        * gfortran.h (gfc_get_uop_from_name, gfc_get_name_from_uop): Declare.
        * symbol.c (gfc_get_uop_from_name, gfc_get_name_from_uop): Define.
        * module.c (load_omp_udrs): Use them.
---
 gcc/fortran/gfortran.h |  2 ++
 gcc/fortran/module.c   | 21 +++------------------
 gcc/fortran/symbol.c   | 21 +++++++++++++++++++++
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 9378b4b8a24..afe9f2354ee 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3399,6 +3399,8 @@ void gfc_delete_symtree (gfc_symtree **, const char *);
 gfc_symtree *gfc_get_unique_symtree (gfc_namespace *);
 gfc_user_op *gfc_get_uop (const char *);
 gfc_user_op *gfc_find_uop (const char *, gfc_namespace *);
+const char *gfc_get_uop_from_name (const char*);
+const char *gfc_get_name_from_uop (const char*);
 void gfc_free_symbol (gfc_symbol *&);
 void gfc_release_symbol (gfc_symbol *&);
 gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *);
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 7b98ba539d6..1328414e4f7 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -5027,7 +5027,7 @@ load_omp_udrs (void)
   while (peek_atom () != ATOM_RPAREN)
     {
       const char *name = NULL, *newname;
-      char *altname;
+      const char *altname = NULL;
       gfc_typespec ts;
       gfc_symtree *st;
       gfc_omp_reduction_op rop = OMP_REDUCTION_USER;
@@ -5054,15 +5054,8 @@ load_omp_udrs (void)
          else if (strcmp (p, ".neqv.") == 0)
            rop = OMP_REDUCTION_NEQV;
        }
-      altname = NULL;
       if (rop == OMP_REDUCTION_USER && name[0] == '.')
-       {
-         size_t len = strlen (name + 1);
-         altname = XALLOCAVEC (char, len);
-         gcc_assert (name[len] == '.');
-         memcpy (altname, name + 1, len - 1);
-         altname[len - 1] = '\0';
-       }
+       altname = gfc_get_name_from_uop (name);
       newname = name;
       if (rop == OMP_REDUCTION_USER)
        newname = find_use_name (altname ? altname : name, !!altname);
@@ -5074,15 +5067,7 @@ load_omp_udrs (void)
          continue;
        }
       if (altname && newname != altname)
-       {
-         size_t len = strlen (newname);
-         altname = XALLOCAVEC (char, len + 3);
-         altname[0] = '.';
-         memcpy (altname + 1, newname, len);
-         altname[len + 1] = '.';
-         altname[len + 2] = '\0';
-         name = gfc_get_string ("%s", altname);
-       }
+       name = altname = gfc_get_uop_from_name (newname);
       st = gfc_find_symtree (gfc_current_ns->omp_udr_root, name);
       gfc_omp_udr *udr = gfc_omp_udr_find (st, &ts);
       if (udr)
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 289d85734bd..900ab49c478 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -3044,6 +3044,27 @@ gfc_find_uop (const char *name, gfc_namespace *ns)
   return (st == NULL) ? NULL : st->n.uop;
 }
 
+/* Given a name return a string usable as user operator name.  */
+const char *
+gfc_get_uop_from_name (const char* name) {
+  gcc_assert (name[0] != '.');
+  return gfc_get_string (".%s.", name);
+}
+
+/* Given a user operator name return a string usable as name.  */
+const char *
+gfc_get_name_from_uop (const char* name) {
+  gcc_assert (name[0] == '.');
+  const size_t len = strlen (name) - 1;
+  gcc_assert (len > 1);
+  gcc_assert (name[len] == '.');
+  char *buffer = XNEWVEC (char, len);
+  memcpy (buffer, name + 1, len - 1);
+  buffer[len - 1] = '\0';
+  const char *ret = gfc_get_string ("%s", buffer);
+  XDELETEVEC (buffer);
+  return ret;
+}
 
 /* Update a symbol's common_block field, and take care of the associated
    memory management.  */
-- 
2.33.0

Reply via email to