aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/primary.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2006-12-31 06:55:16 +0000
committerPaul Thomas <pault@gcc.gnu.org>2006-12-31 06:55:16 +0000
commit7fcafa718da6cb8e072bcadde5eab440df5898d0 (patch)
tree6103da430695e877961c11f0de7a098d90d6f0c2 /gcc/fortran/primary.c
parente7e9c63d558d1e7a564d7542038615b980710272 (diff)
downloadgcc-7fcafa718da6cb8e072bcadde5eab440df5898d0.zip
gcc-7fcafa718da6cb8e072bcadde5eab440df5898d0.tar.gz
gcc-7fcafa718da6cb8e072bcadde5eab440df5898d0.tar.bz2
re PR fortran/23060 (%VAL, %REF and %DESCR constructs not implemented)
2006-12-31 Paul Thomas <pault@gcc.gnu.org> PR fortran/23060 * intrinsic.c (compare_actual_formal ): Distinguish argument list functions from keywords. * intrinsic.c (sort_actual): If formal is NULL, the presence of an argument list function actual is an error. * trans-expr.c (conv_arglist_function) : New function to implement argument list functions %VAL, %REF and %LOC. (gfc_conv_function_call): Call it. * resolve.c (resolve_actual_arglist): Add arg ptype and check argument list functions. (resolve_function, resolve_call): Set value of ptype before calls to resolve_actual_arglist. * primary.c (match_arg_list_function): New function. (gfc_match_actual_arglist): Call it before trying for a keyword argument. 2006-12-31 Paul Thomas <pault@gcc.gnu.org> PR fortran/23060 * gfortran.dg/c_by_val.c: Called by c_by_val_1.f. * gfortran.dg/c_by_val_1.f: New test. * gfortran.dg/c_by_val_2.f: New test. * gfortran.dg/c_by_val_3.f: New test. From-SVN: r120295
Diffstat (limited to 'gcc/fortran/primary.c')
-rw-r--r--gcc/fortran/primary.c91
1 files changed, 87 insertions, 4 deletions
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 66ac2f1..f67500c 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1429,6 +1429,80 @@ cleanup:
}
+/* Match an argument list function, such as %VAL. */
+
+static match
+match_arg_list_function (gfc_actual_arglist *result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ locus old_locus;
+ match m;
+
+ old_locus = gfc_current_locus;
+
+ if (gfc_match_char ('%') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ m = gfc_match ("%n (", name);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (name[0] != '\0')
+ {
+ switch (name[0])
+ {
+ case 'l':
+ if (strncmp(name, "loc", 3) == 0)
+ {
+ result->name = "%LOC";
+ break;
+ }
+ case 'r':
+ if (strncmp(name, "ref", 3) == 0)
+ {
+ result->name = "%REF";
+ break;
+ }
+ case 'v':
+ if (strncmp(name, "val", 3) == 0)
+ {
+ result->name = "%VAL";
+ break;
+ }
+ default:
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ }
+
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: argument list "
+ "function at %C") == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ m = match_actual_arg (&result->expr);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_current_locus = old_locus;
+ return m;
+}
+
+
/* Matches an actual argument list of a function or subroutine, from
the opening parenthesis to the closing parenthesis. The argument
list is assumed to allow keyword arguments because we don't know if
@@ -1497,13 +1571,21 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist ** argp)
}
else
{
- /* See if we have the first keyword argument. */
- m = match_keyword_arg (tail, head);
- if (m == MATCH_YES)
- seen_keyword = 1;
+ /* Try an argument list function, like %VAL. */
+ m = match_arg_list_function (tail);
if (m == MATCH_ERROR)
goto cleanup;
+ /* See if we have the first keyword argument. */
+ if (m == MATCH_NO)
+ {
+ m = match_keyword_arg (tail, head);
+ if (m == MATCH_YES)
+ seen_keyword = 1;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
if (m == MATCH_NO)
{
/* Try for a non-keyword argument. */
@@ -1515,6 +1597,7 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist ** argp)
}
}
+
next:
if (gfc_match_char (')') == MATCH_YES)
break;