Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 46 additions & 29 deletions flang/lib/Parser/prescan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1380,19 +1380,23 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
}
}
} else { // Normal case: not in a compiler directive.
// !$ conditional compilation lines may be continuations when not
// Conditional compilation lines may be continuations when not
// just preprocessing.
if (!preprocessingOnly_ && IsFixedFormCommentChar(col1) &&
nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
nextLine_[4] == ' ' && IsCompilerDirectiveSentinel(&nextLine_[1], 1)) {
if (const char *col6{nextLine_ + 5};
*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
if (atNewline && !IsSpace(nextLine_ + 6)) {
brokenToken_ = true;
if (!preprocessingOnly_ && IsFixedFormCommentChar(col1)) {
if ((nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
nextLine_[4] == ' ' &&
IsCompilerDirectiveSentinel(&nextLine_[1], 1)) ||
(nextLine_[1] == '@' &&
IsCompilerDirectiveSentinel(&nextLine_[1], 4))) {
if (const char *col6{nextLine_ + 5};
*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
if (atNewline && !IsSpace(nextLine_ + 6)) {
brokenToken_ = true;
}
return nextLine_ + 6;
} else {
return nullptr;
}
return nextLine_ + 6;
} else {
return nullptr;
}
}
if (col1 == '&' &&
Expand Down Expand Up @@ -1427,6 +1431,15 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
return nullptr; // not a continuation line
}

constexpr bool IsDirective(const char *match, const char *dir) {
for (; *match; ++match) {
if (*match != ToLowerCaseLetter(*dir++)) {
return false;
}
}
return true;
}

const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
const char *lineStart{nextLine_};
const char *p{lineStart};
Expand All @@ -1439,12 +1452,18 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
if (preprocessingOnly_) {
// in -E mode, don't treat !$ as a continuation
return nullptr;
} else if (p[0] == '!' && p[1] == '$') {
// accept but do not require a matching sentinel
if (p[2] != '&' && !IsSpaceOrTab(&p[2])) {
return nullptr; // not !$
}
} else if (p[0] == '!' && (p[1] == '$' || p[1] == '@')) {
p += 2;
if (InOpenACCOrCUDAConditionalLine()) {
if (IsDirective("acc", p) || IsDirective("cuf", p)) {
p += 3;
} else {
return nullptr;
}
}
if (*p != '&' && !IsSpaceOrTab(p)) {
return nullptr;
}
}
} else if (*p++ == '!') {
for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) {
Expand All @@ -1467,10 +1486,17 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
return nullptr;
}
}
if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ &&
features_.IsEnabled(LanguageFeature::OpenMP)) {
// !$ conditional line can be a continuation
p = lineStart = SkipWhiteSpace(p + 2);
if (p[0] == '!' && !preprocessingOnly_) {
// Conditional lines can be continuations
if (p[1] == '$' && features_.IsEnabled(LanguageFeature::OpenMP)) {
p = lineStart = SkipWhiteSpace(p + 2);
} else if (IsDirective("@acc", p + 1) &&
features_.IsEnabled(LanguageFeature::OpenACC)) {
p = lineStart = SkipWhiteSpace(p + 5);
} else if (IsDirective("@cuf", p + 1) &&
features_.IsEnabled(LanguageFeature::CUDA)) {
p = lineStart = SkipWhiteSpace(p + 5);
}
}
if (*p == '&') {
return p + 1;
Expand Down Expand Up @@ -1706,15 +1732,6 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
return std::nullopt;
}

constexpr bool IsDirective(const char *match, const char *dir) {
for (; *match; ++match) {
if (*match != ToLowerCaseLetter(*dir++)) {
return false;
}
}
return true;
}

Prescanner::LineClassification Prescanner::ClassifyLine(
const char *start) const {
if (inFixedForm_) {
Expand Down
6 changes: 6 additions & 0 deletions flang/test/Preprocessing/bug164727.cuf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
!RUN: %flang_fc1 -fdebug-unparse -x cuda %s 2>&1 | FileCheck %s
!CHECK: REAL, MANAGED, ALLOCATABLE :: x
real, &
!@cuf managed, &
allocatable :: x
end