mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 04:14:03 +08:00
[flang] Fix minor nits with INCLUDE line recognition
Fix some problems with INCLUDE line recognition pointed out by some recently-added tests to the LLVM test suite. Differential Revision: https://reviews.llvm.org/D155497
This commit is contained in:
@@ -285,6 +285,10 @@ end
|
||||
it's an error only if the resolution is ambiguous.
|
||||
* An entity may appear in a `DATA` statement before its explicit
|
||||
type declaration under `IMPLICIT NONE(TYPE)`.
|
||||
* INCLUDE lines can start in any column, can be preceded in
|
||||
fixed form source by a '0' in column 6, can contain spaces
|
||||
between the letters of the word INCLUDE, and can have a
|
||||
numeric character literal kind prefix on the file name.
|
||||
|
||||
### Extensions supported when enabled by options
|
||||
|
||||
@@ -412,6 +416,9 @@ end
|
||||
This is especially desirable when two generics of the same
|
||||
name are combined due to USE association and the mixture may
|
||||
be inadvertent.
|
||||
* Since Fortran 90, INCLUDE lines have been allowed to have
|
||||
a numeric kind parameter prefix on the file name. No other
|
||||
Fortran compiler supports them that I can find.
|
||||
|
||||
## Behavior in cases where the standard is ambiguous or indefinite
|
||||
|
||||
|
||||
@@ -847,12 +847,25 @@ const char *Prescanner::IsFreeFormComment(const char *p) const {
|
||||
|
||||
std::optional<std::size_t> Prescanner::IsIncludeLine(const char *start) const {
|
||||
const char *p{SkipWhiteSpace(start)};
|
||||
for (char ch : "include"s) {
|
||||
if (ToLowerCaseLetter(*p++) != ch) {
|
||||
if (*p == '0' && inFixedForm_ && p == start + 5) {
|
||||
// Accept " 0INCLUDE" in fixed form.
|
||||
p = SkipWhiteSpace(p + 1);
|
||||
}
|
||||
for (const char *q{"include"}; *q; ++q) {
|
||||
if (ToLowerCaseLetter(*p) != *q) {
|
||||
return std::nullopt;
|
||||
}
|
||||
p = SkipWhiteSpace(p + 1);
|
||||
}
|
||||
if (IsDecimalDigit(*p)) { // accept & ignore a numeric kind prefix
|
||||
for (p = SkipWhiteSpace(p + 1); IsDecimalDigit(*p);
|
||||
p = SkipWhiteSpace(p + 1)) {
|
||||
}
|
||||
if (*p != '_') {
|
||||
return std::nullopt;
|
||||
}
|
||||
p = SkipWhiteSpace(p + 1);
|
||||
}
|
||||
p = SkipWhiteSpace(p);
|
||||
if (*p == '"' || *p == '\'') {
|
||||
return {p - start};
|
||||
}
|
||||
@@ -1022,7 +1035,11 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
|
||||
nextLine_[3] == ' ' && nextLine_[4] == ' ') {
|
||||
char col6{nextLine_[5]};
|
||||
if (col6 != '\n' && col6 != '\t' && col6 != ' ' && col6 != '0') {
|
||||
return nextLine_ + 6;
|
||||
if ((col6 == 'i' || col6 == 'I') && IsIncludeLine(nextLine_)) {
|
||||
// It's An INCLUDE line, not a continuation
|
||||
} else {
|
||||
return nextLine_ + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsImplicitContinuation()) {
|
||||
|
||||
1
flang/test/Parser/Inputs/include-file
Normal file
1
flang/test/Parser/Inputs/include-file
Normal file
@@ -0,0 +1 @@
|
||||
x = 1
|
||||
68
flang/test/Parser/include.f
Normal file
68
flang/test/Parser/include.f
Normal file
@@ -0,0 +1,68 @@
|
||||
! RUN: %flang_fc1 -E -I %S/Inputs %s 2>&1 | FileCheck %s
|
||||
include 'include-file'
|
||||
include "include-file"
|
||||
include 1_'include-file'
|
||||
include 1_"include-file"
|
||||
i n c l u d e 'include-file'
|
||||
INCLUDE 'include-file'
|
||||
I N C L U D E 'include-file'
|
||||
include 'include-file'
|
||||
include "include-file"
|
||||
include 1_'include-file'
|
||||
include 1_"include-file"
|
||||
i n c l u d e 'include-file'
|
||||
INCLUDE 'include-file'
|
||||
I N C L U D E 'include-file'
|
||||
0include 'include-file'
|
||||
x = 2
|
||||
include 'include-file'
|
||||
print *, "
|
||||
1include 'not-an-include'
|
||||
2"
|
||||
cinclude 'not-an-include'
|
||||
*include 'not-an-include'
|
||||
!include 'not-an-include'
|
||||
c include 'not-an-include'
|
||||
* include 'not-an-include'
|
||||
! include 'not-an-include'
|
||||
end
|
||||
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include.f" 17
|
||||
!CHECK: x = 2
|
||||
!CHECK:#line "{{.*[/\\]}}include-file" 1
|
||||
!CHECK: x = 1
|
||||
!CHECK:#line "{{.*[/\\]}}include.f" 19
|
||||
!CHECK: print *, " &
|
||||
!CHECK: &include 'not-an-include' &
|
||||
!CHECK: &"
|
||||
!CHECK: end
|
||||
Reference in New Issue
Block a user