Skip to content

Commit c6d99d6

Browse files
klausleraokblast
authored andcommitted
[flang] Line continuation for !@acc and !@Cuf conditional lines (llvm#164475)
Some Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@Cuf conditional lines. Make them less particular. Fixes llvm#164470.
1 parent 44e3f51 commit c6d99d6

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

flang/lib/Parser/prescan.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,9 @@ void Prescanner::Statement() {
140140
CHECK(*at_ == '!');
141141
}
142142
std::optional<int> condOffset;
143-
if (InOpenMPConditionalLine()) {
143+
if (InOpenMPConditionalLine()) { // !$
144144
condOffset = 2;
145-
} else if (directiveSentinel_[0] == '@' && directiveSentinel_[1] == 'c' &&
146-
directiveSentinel_[2] == 'u' && directiveSentinel_[3] == 'f' &&
147-
directiveSentinel_[4] == '\0') {
148-
// CUDA conditional compilation line.
149-
condOffset = 5;
150-
} else if (directiveSentinel_[0] == '@' && directiveSentinel_[1] == 'a' &&
151-
directiveSentinel_[2] == 'c' && directiveSentinel_[3] == 'c' &&
152-
directiveSentinel_[4] == '\0') {
153-
// OpenACC conditional compilation line.
145+
} else if (InOpenACCOrCUDAConditionalLine()) { // !@acc or !@cuf
154146
condOffset = 5;
155147
}
156148
if (condOffset && !preprocessingOnly_) {
@@ -166,7 +158,8 @@ void Prescanner::Statement() {
166158
} else {
167159
// Compiler directive. Emit normalized sentinel, squash following spaces.
168160
// Conditional compilation lines (!$) take this path in -E mode too
169-
// so that -fopenmp only has to appear on the later compilation.
161+
// so that -fopenmp only has to appear on the later compilation
162+
// (ditto for !@cuf and !@acc).
170163
EmitChar(tokens, '!');
171164
++at_, ++column_;
172165
for (const char *sp{directiveSentinel_}; *sp != '\0';
@@ -202,7 +195,7 @@ void Prescanner::Statement() {
202195
}
203196
tokens.CloseToken();
204197
SkipSpaces();
205-
if (InOpenMPConditionalLine() && inFixedForm_ && !tabInCurrentLine_ &&
198+
if (InConditionalLine() && inFixedForm_ && !tabInCurrentLine_ &&
206199
column_ == 6 && *at_ != '\n') {
207200
// !$ 0 - turn '0' into a space
208201
// !$ 1 - turn '1' into '&'
@@ -347,7 +340,7 @@ void Prescanner::Statement() {
347340
while (CompilerDirectiveContinuation(tokens, line.sentinel)) {
348341
newlineProvenance = GetCurrentProvenance();
349342
}
350-
if (preprocessingOnly_ && inFixedForm_ && InOpenMPConditionalLine() &&
343+
if (preprocessingOnly_ && inFixedForm_ && InConditionalLine() &&
351344
nextLine_ < limit_) {
352345
// In -E mode, when the line after !$ conditional compilation is a
353346
// regular fixed form continuation line, append a '&' to the line.
@@ -1360,11 +1353,10 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
13601353
features_.IsEnabled(LanguageFeature::OldDebugLines))) &&
13611354
nextLine_[1] == ' ' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
13621355
nextLine_[4] == ' '};
1363-
if (InCompilerDirective() &&
1364-
!(InOpenMPConditionalLine() && !preprocessingOnly_)) {
1356+
if (InCompilerDirective() && !(InConditionalLine() && !preprocessingOnly_)) {
13651357
// !$ under -E is not continued, but deferred to later compilation
13661358
if (IsFixedFormCommentChar(col1) &&
1367-
!(InOpenMPConditionalLine() && preprocessingOnly_)) {
1359+
!(InConditionalLine() && preprocessingOnly_)) {
13681360
int j{1};
13691361
for (; j < 5; ++j) {
13701362
char ch{directiveSentinel_[j - 1]};
@@ -1443,7 +1435,7 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
14431435
}
14441436
p = SkipWhiteSpaceIncludingEmptyMacros(p);
14451437
if (InCompilerDirective()) {
1446-
if (InOpenMPConditionalLine()) {
1438+
if (InConditionalLine()) {
14471439
if (preprocessingOnly_) {
14481440
// in -E mode, don't treat !$ as a continuation
14491441
return nullptr;

flang/lib/Parser/prescan.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,17 @@ class Prescanner {
171171
bool InOpenMPConditionalLine() const {
172172
return directiveSentinel_ && directiveSentinel_[0] == '$' &&
173173
!directiveSentinel_[1];
174-
;
174+
}
175+
bool InOpenACCOrCUDAConditionalLine() const {
176+
return directiveSentinel_ && directiveSentinel_[0] == '@' &&
177+
((directiveSentinel_[1] == 'a' && directiveSentinel_[2] == 'c' &&
178+
directiveSentinel_[3] == 'c') ||
179+
(directiveSentinel_[1] == 'c' && directiveSentinel_[2] == 'u' &&
180+
directiveSentinel_[3] == 'f')) &&
181+
directiveSentinel_[4] == '\0';
182+
}
183+
bool InConditionalLine() const {
184+
return InOpenMPConditionalLine() || InOpenACCOrCUDAConditionalLine();
175185
}
176186
bool InFixedFormSource() const {
177187
return inFixedForm_ && !inPreprocessorDirective_ && !InCompilerDirective();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
!RUN: %flang_fc1 -x cuda -fdebug-unparse %s 2>&1 | FileCheck %s
2+
!CHECK: ATTRIBUTES(DEVICE) FUNCTION foo()
3+
!@cuf attributes(device) &
4+
function foo()
5+
foo = 1.
6+
end

0 commit comments

Comments
 (0)