Skip to content

Commit

Permalink
[OpenACC] Implement 'collapse' clause parsing.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
erichkeane committed Jan 17, 2024
1 parent 82811a8 commit 3a82a1c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/OpenACCKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ enum class OpenACCClauseKind {
/// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
/// constructs.
Reduction,
/// 'collapse' clause, allowed on 'loop' and Combined constructs.
Collapse,

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

case OpenACCClauseKind::Collapse:
return Out << "collapse";

case OpenACCClauseKind::Invalid:
return Out << "<invalid>";
}
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
.Case("attach", OpenACCClauseKind::Attach)
.Case("auto", OpenACCClauseKind::Auto)
.Case("create", OpenACCClauseKind::Create)
.Case("collapse", OpenACCClauseKind::Collapse)
.Case("copy", OpenACCClauseKind::Copy)
.Case("copyin", OpenACCClauseKind::CopyIn)
.Case("copyout", OpenACCClauseKind::CopyOut)
Expand Down Expand Up @@ -151,6 +152,7 @@ enum class OpenACCSpecialTokenKind {
DevNum,
Queues,
Zero,
Force,
};

bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
Expand All @@ -166,6 +168,8 @@ bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
return Tok.getIdentifierInfo()->isStr("queues");
case OpenACCSpecialTokenKind::Zero:
return Tok.getIdentifierInfo()->isStr("zero");
case OpenACCSpecialTokenKind::Force:
return Tok.getIdentifierInfo()->isStr("force");
}
llvm_unreachable("Unknown 'Kind' Passed");
}
Expand Down Expand Up @@ -462,6 +466,7 @@ ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
case OpenACCClauseKind::Link:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::Reduction:
case OpenACCClauseKind::Collapse:
return ClauseParensKind::Required;

case OpenACCClauseKind::Auto:
Expand Down Expand Up @@ -654,6 +659,15 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
if (ParseOpenACCClauseVarList(Kind))
return true;
break;
case OpenACCClauseKind::Collapse: {
tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force,
Kind);
ExprResult NumLoops =
getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (NumLoops.isInvalid())
return true;
break;
}
default:
llvm_unreachable("Not a required parens type?");
}
Expand Down
39 changes: 39 additions & 0 deletions clang/test/ParserOpenACC/parse-clauses.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,45 @@ void func() {
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop seq,

// expected-error@+2{{expected '('}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse
for(;;){}

// expected-error@+2{{expected expression}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse()
for(;;){}

// expected-error@+3{{invalid tag 'unknown' on 'collapse' clause}}
// expected-error@+2{{expected expression}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(unknown:)
for(;;){}

// expected-error@+2{{expected expression}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(force:)
for(;;){}

// expected-error@+2{{invalid tag 'unknown' on 'collapse' clause}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(unknown:5)
for(;;){}

// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(force:5)
for(;;){}

// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(5)
for(;;){}

// expected-error@+3{{expected ')'}}
// expected-note@+2{{to match this '('}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(5, 6)
for(;;){}
}

void DefaultClause() {
Expand Down
20 changes: 20 additions & 0 deletions clang/test/ParserOpenACC/parse-clauses.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 %s -verify -fopenacc

template<unsigned I, typename T>
void templ() {
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(I)
for(;;){}

// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop collapse(T::value)
for(;;){}
}

struct S {
static constexpr unsigned value = 5;
};

void use() {
templ<7, S>();
}

0 comments on commit 3a82a1c

Please sign in to comment.