Skip to content

Commit 3a82a1c

Browse files
committed
[OpenACC] Implement 'collapse' clause parsing.
The 'collapse' clause takes an optional 'force:' followed by an integer constant expression. For now, parse this as an assignment expression, and we'll check it for value/ICE later.
1 parent 82811a8 commit 3a82a1c

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

clang/include/clang/Basic/OpenACCKinds.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ enum class OpenACCClauseKind {
217217
/// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
218218
/// constructs.
219219
Reduction,
220+
/// 'collapse' clause, allowed on 'loop' and Combined constructs.
221+
Collapse,
220222

221223
/// Represents an invalid clause, for the purposes of parsing.
222224
Invalid,
@@ -312,6 +314,9 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
312314
case OpenACCClauseKind::Reduction:
313315
return Out << "reduction";
314316

317+
case OpenACCClauseKind::Collapse:
318+
return Out << "collapse";
319+
315320
case OpenACCClauseKind::Invalid:
316321
return Out << "<invalid>";
317322
}

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
9292
.Case("attach", OpenACCClauseKind::Attach)
9393
.Case("auto", OpenACCClauseKind::Auto)
9494
.Case("create", OpenACCClauseKind::Create)
95+
.Case("collapse", OpenACCClauseKind::Collapse)
9596
.Case("copy", OpenACCClauseKind::Copy)
9697
.Case("copyin", OpenACCClauseKind::CopyIn)
9798
.Case("copyout", OpenACCClauseKind::CopyOut)
@@ -151,6 +152,7 @@ enum class OpenACCSpecialTokenKind {
151152
DevNum,
152153
Queues,
153154
Zero,
155+
Force,
154156
};
155157

156158
bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
@@ -166,6 +168,8 @@ bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
166168
return Tok.getIdentifierInfo()->isStr("queues");
167169
case OpenACCSpecialTokenKind::Zero:
168170
return Tok.getIdentifierInfo()->isStr("zero");
171+
case OpenACCSpecialTokenKind::Force:
172+
return Tok.getIdentifierInfo()->isStr("force");
169173
}
170174
llvm_unreachable("Unknown 'Kind' Passed");
171175
}
@@ -462,6 +466,7 @@ ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
462466
case OpenACCClauseKind::Link:
463467
case OpenACCClauseKind::Host:
464468
case OpenACCClauseKind::Reduction:
469+
case OpenACCClauseKind::Collapse:
465470
return ClauseParensKind::Required;
466471

467472
case OpenACCClauseKind::Auto:
@@ -654,6 +659,15 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
654659
if (ParseOpenACCClauseVarList(Kind))
655660
return true;
656661
break;
662+
case OpenACCClauseKind::Collapse: {
663+
tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force,
664+
Kind);
665+
ExprResult NumLoops =
666+
getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
667+
if (NumLoops.isInvalid())
668+
return true;
669+
break;
670+
}
657671
default:
658672
llvm_unreachable("Not a required parens type?");
659673
}

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,45 @@ void func() {
5454
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
5555
#pragma acc loop seq,
5656

57+
// expected-error@+2{{expected '('}}
58+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
59+
#pragma acc loop collapse
60+
for(;;){}
61+
62+
// expected-error@+2{{expected expression}}
63+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
64+
#pragma acc loop collapse()
65+
for(;;){}
66+
67+
// expected-error@+3{{invalid tag 'unknown' on 'collapse' clause}}
68+
// expected-error@+2{{expected expression}}
69+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
70+
#pragma acc loop collapse(unknown:)
71+
for(;;){}
72+
73+
// expected-error@+2{{expected expression}}
74+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
75+
#pragma acc loop collapse(force:)
76+
for(;;){}
77+
78+
// expected-error@+2{{invalid tag 'unknown' on 'collapse' clause}}
79+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
80+
#pragma acc loop collapse(unknown:5)
81+
for(;;){}
82+
83+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
84+
#pragma acc loop collapse(force:5)
85+
for(;;){}
86+
87+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
88+
#pragma acc loop collapse(5)
89+
for(;;){}
90+
91+
// expected-error@+3{{expected ')'}}
92+
// expected-note@+2{{to match this '('}}
93+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
94+
#pragma acc loop collapse(5, 6)
95+
for(;;){}
5796
}
5897

5998
void DefaultClause() {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %clang_cc1 %s -verify -fopenacc
2+
3+
template<unsigned I, typename T>
4+
void templ() {
5+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
6+
#pragma acc loop collapse(I)
7+
for(;;){}
8+
9+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
10+
#pragma acc loop collapse(T::value)
11+
for(;;){}
12+
}
13+
14+
struct S {
15+
static constexpr unsigned value = 5;
16+
};
17+
18+
void use() {
19+
templ<7, S>();
20+
}

0 commit comments

Comments
 (0)