Skip to content

Commit af34890

Browse files
authored
[flang] Let !@acc and !@Cuf conditional lines be continuations (llvm#164892)
OpenMP conditional compilation lines (!$) work as continuation lines, but OpenACC and CUDA conditional lines do not. Fixes llvm#164727 and llvm#164708.
1 parent e34d603 commit af34890

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

flang/lib/Parser/prescan.cpp

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,19 +1380,23 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
13801380
}
13811381
}
13821382
} else { // Normal case: not in a compiler directive.
1383-
// !$ conditional compilation lines may be continuations when not
1383+
// Conditional compilation lines may be continuations when not
13841384
// just preprocessing.
1385-
if (!preprocessingOnly_ && IsFixedFormCommentChar(col1) &&
1386-
nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
1387-
nextLine_[4] == ' ' && IsCompilerDirectiveSentinel(&nextLine_[1], 1)) {
1388-
if (const char *col6{nextLine_ + 5};
1389-
*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
1390-
if (atNewline && !IsSpace(nextLine_ + 6)) {
1391-
brokenToken_ = true;
1385+
if (!preprocessingOnly_ && IsFixedFormCommentChar(col1)) {
1386+
if ((nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
1387+
nextLine_[4] == ' ' &&
1388+
IsCompilerDirectiveSentinel(&nextLine_[1], 1)) ||
1389+
(nextLine_[1] == '@' &&
1390+
IsCompilerDirectiveSentinel(&nextLine_[1], 4))) {
1391+
if (const char *col6{nextLine_ + 5};
1392+
*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
1393+
if (atNewline && !IsSpace(nextLine_ + 6)) {
1394+
brokenToken_ = true;
1395+
}
1396+
return nextLine_ + 6;
1397+
} else {
1398+
return nullptr;
13921399
}
1393-
return nextLine_ + 6;
1394-
} else {
1395-
return nullptr;
13961400
}
13971401
}
13981402
if (col1 == '&' &&
@@ -1427,6 +1431,15 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
14271431
return nullptr; // not a continuation line
14281432
}
14291433

1434+
constexpr bool IsDirective(const char *match, const char *dir) {
1435+
for (; *match; ++match) {
1436+
if (*match != ToLowerCaseLetter(*dir++)) {
1437+
return false;
1438+
}
1439+
}
1440+
return true;
1441+
}
1442+
14301443
const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
14311444
const char *lineStart{nextLine_};
14321445
const char *p{lineStart};
@@ -1439,12 +1452,18 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
14391452
if (preprocessingOnly_) {
14401453
// in -E mode, don't treat !$ as a continuation
14411454
return nullptr;
1442-
} else if (p[0] == '!' && p[1] == '$') {
1443-
// accept but do not require a matching sentinel
1444-
if (p[2] != '&' && !IsSpaceOrTab(&p[2])) {
1445-
return nullptr; // not !$
1446-
}
1455+
} else if (p[0] == '!' && (p[1] == '$' || p[1] == '@')) {
14471456
p += 2;
1457+
if (InOpenACCOrCUDAConditionalLine()) {
1458+
if (IsDirective("acc", p) || IsDirective("cuf", p)) {
1459+
p += 3;
1460+
} else {
1461+
return nullptr;
1462+
}
1463+
}
1464+
if (*p != '&' && !IsSpaceOrTab(p)) {
1465+
return nullptr;
1466+
}
14481467
}
14491468
} else if (*p++ == '!') {
14501469
for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) {
@@ -1467,10 +1486,17 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
14671486
return nullptr;
14681487
}
14691488
}
1470-
if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ &&
1471-
features_.IsEnabled(LanguageFeature::OpenMP)) {
1472-
// !$ conditional line can be a continuation
1473-
p = lineStart = SkipWhiteSpace(p + 2);
1489+
if (p[0] == '!' && !preprocessingOnly_) {
1490+
// Conditional lines can be continuations
1491+
if (p[1] == '$' && features_.IsEnabled(LanguageFeature::OpenMP)) {
1492+
p = lineStart = SkipWhiteSpace(p + 2);
1493+
} else if (IsDirective("@acc", p + 1) &&
1494+
features_.IsEnabled(LanguageFeature::OpenACC)) {
1495+
p = lineStart = SkipWhiteSpace(p + 5);
1496+
} else if (IsDirective("@cuf", p + 1) &&
1497+
features_.IsEnabled(LanguageFeature::CUDA)) {
1498+
p = lineStart = SkipWhiteSpace(p + 5);
1499+
}
14741500
}
14751501
if (*p == '&') {
14761502
return p + 1;
@@ -1706,15 +1732,6 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
17061732
return std::nullopt;
17071733
}
17081734

1709-
constexpr bool IsDirective(const char *match, const char *dir) {
1710-
for (; *match; ++match) {
1711-
if (*match != ToLowerCaseLetter(*dir++)) {
1712-
return false;
1713-
}
1714-
}
1715-
return true;
1716-
}
1717-
17181735
Prescanner::LineClassification Prescanner::ClassifyLine(
17191736
const char *start) const {
17201737
if (inFixedForm_) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -x cuda %s 2>&1 | FileCheck %s
2+
!CHECK: REAL, MANAGED, ALLOCATABLE :: x
3+
real, &
4+
!@cuf managed, &
5+
allocatable :: x
6+
end

0 commit comments

Comments
 (0)