| Index: gcc/gcc/fortran/scanner.c
|
| diff --git a/gcc/gcc/fortran/scanner.c b/gcc/gcc/fortran/scanner.c
|
| index 1e7ec966efec0009834fbe80efaa23205ecb7c6c..711042ddcb25952cef2107fa5586b988074771a6 100644
|
| --- a/gcc/gcc/fortran/scanner.c
|
| +++ b/gcc/gcc/fortran/scanner.c
|
| @@ -63,9 +63,10 @@ static gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
|
|
|
| static gfc_file *file_head, *current_file;
|
|
|
| -static int continue_flag, end_flag, openmp_flag;
|
| +static int continue_flag, end_flag, openmp_flag, gcc_attribute_flag;
|
| static int continue_count, continue_line;
|
| static locus openmp_locus;
|
| +static locus gcc_attribute_locus;
|
|
|
| gfc_source_form gfc_current_form;
|
| static gfc_linebuf *line_head, *line_tail;
|
| @@ -613,7 +614,7 @@ next_char (void)
|
|
|
| /* Skip a comment. When we come here the parse pointer is positioned
|
| immediately after the comment character. If we ever implement
|
| - compiler directives withing comments, here is where we parse the
|
| + compiler directives within comments, here is where we parse the
|
| directive. */
|
|
|
| static void
|
| @@ -663,6 +664,34 @@ gfc_define_undef_line (void)
|
| }
|
|
|
|
|
| +/* Return true if GCC$ was matched. */
|
| +static bool
|
| +skip_gcc_attribute (locus start)
|
| +{
|
| + bool r = false;
|
| + char c;
|
| + locus old_loc = gfc_current_locus;
|
| +
|
| + if ((c = next_char ()) == 'g' || c == 'G')
|
| + if ((c = next_char ()) == 'c' || c == 'C')
|
| + if ((c = next_char ()) == 'c' || c == 'C')
|
| + if ((c = next_char ()) == '$')
|
| + r = true;
|
| +
|
| + if (r == false)
|
| + gfc_current_locus = old_loc;
|
| + else
|
| + {
|
| + gcc_attribute_flag = 1;
|
| + gcc_attribute_locus = old_loc;
|
| + gfc_current_locus = start;
|
| + }
|
| +
|
| + return r;
|
| +}
|
| +
|
| +
|
| +
|
| /* Comment lines are null lines, lines containing only blanks or lines
|
| on which the first nonblank line is a '!'.
|
| Return true if !$ openmp conditional compilation sentinel was
|
| @@ -694,6 +723,10 @@ skip_free_comments (void)
|
|
|
| if (c == '!')
|
| {
|
| + /* Keep the !GCC$ line. */
|
| + if (at_bol && skip_gcc_attribute (start))
|
| + return false;
|
| +
|
| /* If -fopenmp, we need to handle here 2 things:
|
| 1) don't treat !$omp as comments, but directives
|
| 2) handle OpenMP conditional compilation, where
|
| @@ -752,6 +785,8 @@ skip_free_comments (void)
|
|
|
| if (openmp_flag && at_bol)
|
| openmp_flag = 0;
|
| +
|
| + gcc_attribute_flag = 0;
|
| gfc_current_locus = start;
|
| return false;
|
| }
|
| @@ -806,6 +841,13 @@ skip_fixed_comments (void)
|
|
|
| if (c == '!' || c == 'c' || c == 'C' || c == '*')
|
| {
|
| + if (skip_gcc_attribute (start))
|
| + {
|
| + /* Canonicalize to *$omp. */
|
| + *start.nextc = '*';
|
| + return;
|
| + }
|
| +
|
| /* If -fopenmp, we need to handle here 2 things:
|
| 1) don't treat !$omp|c$omp|*$omp as comments, but directives
|
| 2) handle OpenMP conditional compilation, where
|
| @@ -917,6 +959,7 @@ skip_fixed_comments (void)
|
| }
|
|
|
| openmp_flag = 0;
|
| + gcc_attribute_flag = 0;
|
| gfc_current_locus = start;
|
| }
|
|
|
| @@ -963,6 +1006,11 @@ restart:
|
|
|
| if (!in_string && c == '!')
|
| {
|
| + if (gcc_attribute_flag
|
| + && memcmp (&gfc_current_locus, &gcc_attribute_locus,
|
| + sizeof (gfc_current_locus)) == 0)
|
| + goto done;
|
| +
|
| if (openmp_flag
|
| && memcmp (&gfc_current_locus, &openmp_locus,
|
| sizeof (gfc_current_locus)) == 0)
|
| @@ -1032,6 +1080,17 @@ restart:
|
| }
|
| }
|
|
|
| + /* Check to see if the continuation line was truncated. */
|
| + if (gfc_option.warn_line_truncation && gfc_current_locus.lb != NULL
|
| + && gfc_current_locus.lb->truncated)
|
| + {
|
| + int maxlen = gfc_option.free_line_length;
|
| + gfc_current_locus.lb->truncated = 0;
|
| + gfc_current_locus.nextc += maxlen;
|
| + gfc_warning_now ("Line truncated at %L", &gfc_current_locus);
|
| + gfc_current_locus.nextc -= maxlen;
|
| + }
|
| +
|
| /* Now find where it continues. First eat any comment lines. */
|
| openmp_cond_flag = skip_free_comments ();
|
|
|
| @@ -1091,7 +1150,7 @@ restart:
|
| }
|
| }
|
| }
|
| - else
|
| + else /* Fixed form. */
|
| {
|
| /* Fixed form continuation. */
|
| if (!in_string && c == '!')
|
| @@ -1110,6 +1169,14 @@ restart:
|
| if (c != '\n')
|
| goto done;
|
|
|
| + /* Check to see if the continuation line was truncated. */
|
| + if (gfc_option.warn_line_truncation && gfc_current_locus.lb != NULL
|
| + && gfc_current_locus.lb->truncated)
|
| + {
|
| + gfc_current_locus.lb->truncated = 0;
|
| + gfc_warning_now ("Line truncated at %L", &gfc_current_locus);
|
| + }
|
| +
|
| prev_openmp_flag = openmp_flag;
|
| continue_flag = 1;
|
| old_loc = gfc_current_locus;
|
| @@ -1404,7 +1471,10 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
|
| if (c == '&')
|
| {
|
| if (seen_ampersand)
|
| - seen_ampersand = 0;
|
| + {
|
| + seen_ampersand = 0;
|
| + seen_printable = 1;
|
| + }
|
| else
|
| seen_ampersand = 1;
|
| }
|
|
|