diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2006-12-31 06:55:16 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2006-12-31 06:55:16 +0000 |
commit | 7fcafa718da6cb8e072bcadde5eab440df5898d0 (patch) | |
tree | 6103da430695e877961c11f0de7a098d90d6f0c2 /gcc/fortran/primary.c | |
parent | e7e9c63d558d1e7a564d7542038615b980710272 (diff) | |
download | gcc-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.c | 91 |
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; |