[Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)
Bernhard Reutner-Fischer
rep.dot.nop@gmail.com
Sun Oct 28 09:16:00 GMT 2018
On Sat, 27 Oct 2018 20:03:47 +0100
Paul Richard Thomas <paul.richard.thomas@gmail.com> wrote:
A few nits.
> + /* Pull an inquiry result out of an expression. */
> +
> + static bool
> + find_inquiry_ref (gfc_expr *p, gfc_expr **newp)
> + {
> + gfc_ref *ref;
> + gfc_ref *inquiry = NULL;
> + gfc_expr *tmp;
> +
> + tmp = gfc_copy_expr (p);
> +
> + if (tmp->ref && tmp->ref->type == REF_INQUIRY)
> + {
> + inquiry = tmp->ref;
> + tmp->ref = NULL;
> + }
> + else
> + {
> + for (ref = tmp->ref; ref; ref = ref->next)
> + if (ref->next && ref->next->type == REF_INQUIRY)
> + {
> + inquiry = ref->next;
> + ref->next = NULL;
> + }
> + }
> +
> + if(!inquiry)
missing space before open parenthesis
> *************** typedef struct gfc_ref
> *** 1960,1965 ****
> --- 1963,1970 ----
> }
> ss;
>
> + inquiry_type i;
inq would be easier to understand and unambiguous imho.
> + /* Used by gfc_match_varspec() to match an inquiry reference. */
> +
> + static bool
> + is_inquiry_ref (const char *name, gfc_ref **ref)
> + {
> + inquiry_type type;
> +
> + if (name == NULL)
> + return false;
> +
> + if (ref) *ref = NULL;
> +
> + switch (name[0])
> + {
> + case 'r':
> + if (strcmp (name, "re") == 0)
> + type = INQUIRY_RE;
> + else
> + return false;
> + break;
> +
> + case 'i':
> + if (strcmp (name, "im") == 0)
> + type = INQUIRY_IM;
> + else
> + return false;
> + break;
> +
> + case 'k':
> + if (strcmp (name, "kind") == 0)
> + type = INQUIRY_KIND;
> + else
> + return false;
> + break;
> +
> + case 'l':
> + if (strcmp (name, "len") == 0)
> + type = INQUIRY_LEN;
> + else
> + return false;
> + break;
> +
> + default:
> + return false;
> + }
Is the switch really worth it? I'd have used a plain chain of strcmp,
fwiw.
> ! switch (tmp->u.i)
> ! {
> ! case INQUIRY_RE:
> ! case INQUIRY_IM:
> ! if (!gfc_notify_std (GFC_STD_F2008, "re or im
> part_refs at %C")) ! return MATCH_ERROR;
I guess RE and IM should be capitalised?
> *************** gfc_variable_attr (gfc_expr *expr, gfc_t
> *** 2358,2363 ****
> --- 2521,2527 ----
> gfc_ref *ref;
> gfc_symbol *sym;
> gfc_component *comp;
> + bool has_inquiry_part;
>
> if (expr->expr_type != EXPR_VARIABLE && expr->expr_type !=
> EXPR_FUNCTION) gfc_internal_error ("gfc_variable_attr(): Expression
> isn't a variable"); *************** gfc_variable_attr (gfc_expr
> *expr, gfc_t *** 2387,2392 ****
> --- 2551,2561 ----
> if (ts != NULL && expr->ts.type == BT_UNKNOWN)
> *ts = sym->ts;
>
> + has_inquiry_part = false;
> + for (ref = expr->ref; ref; ref = ref->next)
> + if (ref->type == REF_INQUIRY)
> + has_inquiry_part = true;
you could break here
> +
> for (ref = expr->ref; ref; ref = ref->next)
> switch (ref->type)
> {
> Index: gcc/fortran/trans-expr.c
> ===================================================================
> *** gcc/fortran/trans-expr.c (revision 265411)
> --- gcc/fortran/trans-expr.c (working copy)
> *************** conv_parent_component_references (gfc_se
> *** 2510,2515 ****
> --- 2510,2549 ----
> conv_parent_component_references (se, &parent);
> }
>
> +
> + static void
> + conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr,
> gfc_typespec *ts)
> + {
> + tree res = se->expr;
> +
> + switch (ref->u.i)
> + {
> + case INQUIRY_RE:
> + res = fold_build1_loc (input_location, REALPART_EXPR,
> + TREE_TYPE (TREE_TYPE (res)), res);
> + break;
> +
> + case INQUIRY_IM:
> + res = fold_build1_loc (input_location, IMAGPART_EXPR,
> + TREE_TYPE (TREE_TYPE (res)), res);
> + break;
> +
> + case INQUIRY_KIND:
> + res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
> + ts->kind);
> + break;
> +
> + case INQUIRY_LEN:
> + res = fold_convert (gfc_typenode_for_spec (&expr->ts),
> + se->string_length);
> + break;
> +
> + default:
> + gcc_unreachable ();
> + }
> + se->expr = res;
Don't you have to gfc_free_expr (se->expr) or gfc_replace_expr() ?
cheers,
More information about the Fortran
mailing list