[clang] 9c4e7a1 - [OpenACC] Implement 'self' clause parsing on 'update'.
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 16 09:25:39 PST 2024
Author: erichkeane
Date: 2024-01-16T09:25:34-08:00
New Revision: 9c4e7a159b1f2228ddf146c58c2478418cd63e86
URL: https://github.com/llvm/llvm-project/commit/9c4e7a159b1f2228ddf146c58c2478418cd63e86
DIFF: https://github.com/llvm/llvm-project/commit/9c4e7a159b1f2228ddf146c58c2478418cd63e86.diff
LOG: [OpenACC] Implement 'self' clause parsing on 'update'.
The update directive has its own version of 'self' that has a 'var-list'
instead of a 'condition' (like the serial/parallel/kernel/combined
constructs). This patch special cases it on 'update' to make sure we
parse this correctly.
Added:
Modified:
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseOpenACC.cpp
clang/test/ParserOpenACC/parse-clauses.c
Removed:
################################################################################
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index e50a4d05b459918..fc56de823d7efaf 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3574,11 +3574,12 @@ class Parser : public CodeCompletionHandler {
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
/// Parses any parameters for an OpenACC Clause, including required/optional
/// parens.
- bool ParseOpenACCClauseParams(OpenACCClauseKind Kind);
+ bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind);
/// Parses a single clause in a clause-list for OpenACC.
- bool ParseOpenACCClause();
+ bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
/// Parses the clause-list for an OpenACC directive.
- void ParseOpenACCClauseList();
+ void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
bool ParseOpenACCWaitArgument();
private:
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index d34cc5f799c9553..5196eb9056be281 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -393,10 +393,12 @@ enum ClauseParensKind {
Required
};
-ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
+ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind) {
switch (Kind) {
case OpenACCClauseKind::Self:
- return ClauseParensKind::Optional;
+ return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
+ : ClauseParensKind::Optional;
case OpenACCClauseKind::Default:
case OpenACCClauseKind::If:
@@ -433,12 +435,14 @@ ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
llvm_unreachable("Unhandled clause kind");
}
-bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
- return getClauseParensKind(Kind) == ClauseParensKind::Optional;
+bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind) {
+ return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
}
-bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
- return getClauseParensKind(Kind) == ClauseParensKind::Required;
+bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind) {
+ return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
}
ExprResult ParseOpenACCConditionalExpr(Parser &P) {
@@ -465,7 +469,7 @@ void SkipUntilEndOfDirective(Parser &P) {
// a pqr-list is a comma-separated list of pdr items. The one exception is a
// clause-list, which is a list of one or more clauses optionally separated by
// commas.
-void Parser::ParseOpenACCClauseList() {
+void Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) {
bool FirstClause = true;
while (getCurToken().isNot(tok::annot_pragma_openacc_end)) {
// Comma is optional in a clause-list.
@@ -475,7 +479,7 @@ void Parser::ParseOpenACCClauseList() {
// Recovering from a bad clause is really
diff icult, so we just give up on
// error.
- if (ParseOpenACCClause()) {
+ if (ParseOpenACCClause(DirKind)) {
SkipUntilEndOfDirective(*this);
return;
}
@@ -508,7 +512,7 @@ bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) {
// really have its owner grammar and each individual one has its own definition.
// However, they all are named with a single-identifier (or auto/default!)
// token, followed in some cases by either braces or parens.
-bool Parser::ParseOpenACCClause() {
+bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
// A number of clause names are actually keywords, so accept a keyword that
// can be converted to a name.
if (expectIdentifierOrKeyword(*this))
@@ -523,14 +527,15 @@ bool Parser::ParseOpenACCClause() {
// Consume the clause name.
ConsumeToken();
- return ParseOpenACCClauseParams(Kind);
+ return ParseOpenACCClauseParams(DirKind, Kind);
}
-bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
+bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind) {
BalancedDelimiterTracker Parens(*this, tok::l_paren,
tok::annot_pragma_openacc_end);
- if (ClauseHasRequiredParens(Kind)) {
+ if (ClauseHasRequiredParens(DirKind, Kind)) {
if (Parens.expectAndConsume()) {
// We are missing a paren, so assume that the person just forgot the
// parameter. Return 'false' so we try to continue on and parse the next
@@ -576,6 +581,12 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
if (ParseOpenACCClauseVarList(Kind))
return true;
break;
+ case OpenACCClauseKind::Self:
+ // The 'self' clause is a var-list instead of a 'condition' in the case of
+ // the 'update' clause, so we have to handle it here. U se an assert to
+ // make sure we get the right
diff erentiator.
+ assert(DirKind == OpenACCDirectiveKind::Update);
+ LLVM_FALLTHROUGH;
case OpenACCClauseKind::Attach:
case OpenACCClauseKind::Copy:
case OpenACCClauseKind::Delete:
@@ -598,10 +609,11 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
}
return Parens.consumeClose();
- } else if (ClauseHasOptionalParens(Kind)) {
+ } else if (ClauseHasOptionalParens(DirKind, Kind)) {
if (!Parens.consumeOpen()) {
switch (Kind) {
case OpenACCClauseKind::Self: {
+ assert(DirKind != OpenACCDirectiveKind::Update);
ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
// An invalid expression can be just about anything, so just give up on
// this clause list.
@@ -817,7 +829,7 @@ void Parser::ParseOpenACCDirective() {
}
// Parses the list of clauses, if present.
- ParseOpenACCClauseList();
+ ParseOpenACCClauseList(DirKind);
Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
assert(Tok.is(tok::annot_pragma_openacc_end) &&
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 5cbcf5410845c61..c5638531b68b965 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -306,6 +306,11 @@ void SyncClause() {
#pragma acc serial self(i > j, seq
for(;;){}
+ // expected-warning at +2{{left operand of comma operator has no effect}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(i, j)
+ for(;;){}
+
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc serial self(i > j)
for(;;){}
@@ -323,6 +328,25 @@ struct HasMembersArray {
struct Members MemArr[4];
};
+// On 'update', self behaves
diff erently and requires parens, plus takes a var-list instead.
+void SelfUpdate() {
+ struct Members s;
+
+ // expected-error at +2{{expected '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self
+ for(;;){}
+
+ // expected-error at +2{{use of undeclared identifier 'zero'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self(zero : s.array[s.value : 5], s.value), seq
+ for(;;){}
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self(s.array[s.value : 5], s.value), seq
+ for(;;){}
+}
+
void VarListClauses() {
// expected-error at +2{{expected '('}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
More information about the cfe-commits
mailing list