Skip to content

Commit 7f303b7

Browse files
committed
When calling IsCompilerDirectiveSentinel,the prefix comment character need to be skipped.
Fixes #117693 and also handles continuation lines beginning with Macros
1 parent e33f456 commit 7f303b7

File tree

6 files changed

+82
-4
lines changed

6 files changed

+82
-4
lines changed

flang/include/flang/Parser/token-sequence.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class TokenSequence {
123123
bool HasRedundantBlanks(std::size_t firstChar = 0) const;
124124
TokenSequence &RemoveBlanks(std::size_t firstChar = 0);
125125
TokenSequence &RemoveRedundantBlanks(std::size_t firstChar = 0);
126+
TokenSequence &RemoveRedundantCompilerDirectives(const Prescanner &);
126127
TokenSequence &ClipComment(const Prescanner &, bool skipFirst = false);
127128
const TokenSequence &CheckBadFortranCharacters(
128129
Messages &, const Prescanner &, bool allowAmpersand) const;

flang/lib/Parser/prescan.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void Prescanner::Statement() {
175175
EmitChar(tokens, '!');
176176
++at_, ++column_;
177177
for (const char *sp{directiveSentinel_}; *sp != '\0';
178-
++sp, ++at_, ++column_) {
178+
++sp, ++at_, ++column_) {
179179
EmitChar(tokens, *sp);
180180
}
181181
if (IsSpaceOrTab(at_)) {
@@ -346,6 +346,7 @@ void Prescanner::CheckAndEmitLine(
346346
tokens.CheckBadParentheses(messages_);
347347
}
348348
}
349+
tokens.RemoveRedundantCompilerDirectives(*this);
349350
tokens.Emit(cooked_);
350351
if (omitNewline_) {
351352
omitNewline_ = false;
@@ -511,7 +512,7 @@ bool Prescanner::MustSkipToEndOfLine() const {
511512
if (inFixedForm_ && column_ > fixedFormColumnLimit_ && !tabInCurrentLine_) {
512513
return true; // skip over ignored columns in right margin (73:80)
513514
} else if (*at_ == '!' && !inCharLiteral_) {
514-
return !IsCompilerDirectiveSentinel(at_);
515+
return !IsCompilerDirectiveSentinel(at_ + 1);
515516
} else {
516517
return false;
517518
}
@@ -1073,7 +1074,7 @@ std::optional<std::size_t> Prescanner::IsIncludeLine(const char *start) const {
10731074
}
10741075
if (IsDecimalDigit(*p)) { // accept & ignore a numeric kind prefix
10751076
for (p = SkipWhiteSpace(p + 1); IsDecimalDigit(*p);
1076-
p = SkipWhiteSpace(p + 1)) {
1077+
p = SkipWhiteSpace(p + 1)) {
10771078
}
10781079
if (*p != '_') {
10791080
return std::nullopt;
@@ -1121,7 +1122,7 @@ void Prescanner::FortranInclude(const char *firstQuote) {
11211122
llvm::raw_string_ostream error{buf};
11221123
Provenance provenance{GetProvenance(nextLine_)};
11231124
std::optional<std::string> prependPath;
1124-
if (const SourceFile * currentFile{allSources_.GetSourceFile(provenance)}) {
1125+
if (const SourceFile *currentFile{allSources_.GetSourceFile(provenance)}) {
11251126
prependPath = DirectoryName(currentFile->path());
11261127
}
11271128
const SourceFile *included{

flang/lib/Parser/token-sequence.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,46 @@ TokenSequence &TokenSequence::ClipComment(
304304
return *this;
305305
}
306306

307+
TokenSequence &TokenSequence::RemoveRedundantCompilerDirectives(
308+
const Prescanner &prescanner) {
309+
// When the toekn sqeuence is "<compiler directive> <clause1> <compiler
310+
// directive> <clause2>" convert it to "<compiler directive> <clause1>
311+
// <clause2>"
312+
std::size_t tokens{SizeInTokens()};
313+
TokenSequence result;
314+
bool firstDirective{true};
315+
for (std::size_t j{0}; j < tokens; ++j) {
316+
CharBlock tok{TokenAt(j)};
317+
bool isSentinel{false};
318+
std::size_t blanks{tok.CountLeadingBlanks()};
319+
if (blanks < tok.size() && tok[blanks] == '!') {
320+
// Retain active compiler directive sentinels (e.g. "!dir$", "!$omp")
321+
for (std::size_t k{j + 1}; k < tokens && tok.size() <= blanks + 5; ++k) {
322+
if (tok.begin() + tok.size() == TokenAt(k).begin()) {
323+
tok.ExtendToCover(TokenAt(k));
324+
} else {
325+
break;
326+
}
327+
}
328+
}
329+
if (tok.size() > blanks + 5) {
330+
isSentinel =
331+
prescanner.IsCompilerDirectiveSentinel(&tok[blanks + 1]).has_value();
332+
}
333+
if (isSentinel &&
334+
!firstDirective) { // skip the directives if not the first one
335+
j++;
336+
} else {
337+
result.Put(*this, j);
338+
}
339+
if (isSentinel && firstDirective) {
340+
firstDirective = false;
341+
}
342+
}
343+
swap(result);
344+
return *this;
345+
}
346+
307347
void TokenSequence::Emit(CookedSource &cooked) const {
308348
if (auto n{char_.size()}) {
309349
cooked.Put(&char_[0], n);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: %flang -fopenmp -E %s 2>&1 | FileCheck %s
2+
!CHECK: !$OMP DO SCHEDULE(STATIC)
3+
program main
4+
IMPLICIT NONE
5+
INTEGER:: I
6+
#define OMPSUPPORT
7+
!$ INTEGER :: omp_id
8+
!$OMP PARALLEL DO
9+
OMPSUPPORT !$OMP DO SCHEDULE(STATIC)
10+
DO I=1,100
11+
print *, omp_id
12+
ENDDO
13+
!$OMP END PARALLEL DO
14+
end program
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
! RUN: %flang -fopenmp -E %s 2>&1 | FileCheck %s
2+
!CHECK: !$OMP DO SCHEDULE(STATIC) DEFAULT(NONE)
3+
!CHECK-NOT: !$OMP DEFAULT(NONE)
4+
program main
5+
IMPLICIT NONE
6+
INTEGER:: I
7+
#define OMPSUPPORT
8+
!$ INTEGER :: omp_id
9+
!$OMP PARALLEL DO
10+
OMPSUPPORT !$OMP DO SCHEDULE(STATIC) !$OMP DEFAULT(NONE)
11+
DO I=1,100
12+
print *, omp_id
13+
ENDDO
14+
!$OMP END PARALLEL DO
15+
end program
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
! RUN: %flang -fopenmp -E %s 2>&1 | FileCheck %s
2+
!CHECK-NOT: DO I=1,100 !$OMP
3+
program main
4+
INTEGER::n
5+
DO I=1,100 !!$OMP
6+
ENDDO
7+
END PROGRAM

0 commit comments

Comments
 (0)