[clang] 87f67c2 - [OpenACC] Implement 'self' clause parsing
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 8 12:10:19 PST 2024
Author: erichkeane
Date: 2024-01-08T12:10:13-08:00
New Revision: 87f67c2599410786ea3600d388fd1d2df13e60af
URL: https://github.com/llvm/llvm-project/commit/87f67c2599410786ea3600d388fd1d2df13e60af
DIFF: https://github.com/llvm/llvm-project/commit/87f67c2599410786ea3600d388fd1d2df13e60af.diff
LOG: [OpenACC] Implement 'self' clause parsing
The 'self' clause takes an optional 'condition' expression, same as the
non-optional expression taken by the 'if' clause. This patch extracts
the 'condition' expression to a separate function, and implements the
'optional parens' infrastructure for clauses, then implements 'self'
parsing.
Added:
Modified:
clang/include/clang/Basic/OpenACCKinds.h
clang/lib/Parse/ParseOpenACC.cpp
clang/test/ParserOpenACC/parse-clauses.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index f6a628db29cf48..b0c157e0023600 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -96,6 +96,8 @@ enum class OpenACCClauseKind {
/// 'if' clause, allowed on all the Compute Constructs, Data Constructs,
/// Executable Constructs, and Combined Constructs.
If,
+ /// 'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
+ Self,
/// Represents an invalid clause, for the purposes of parsing.
Invalid,
};
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 84e994ef00816d..c9224d3ae910cd 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -96,6 +96,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
.Case("if_present", OpenACCClauseKind::IfPresent)
.Case("independent", OpenACCClauseKind::Independent)
.Case("nohost", OpenACCClauseKind::NoHost)
+ .Case("self", OpenACCClauseKind::Self)
.Case("seq", OpenACCClauseKind::Seq)
.Case("vector", OpenACCClauseKind::Vector)
.Case("worker", OpenACCClauseKind::Worker)
@@ -328,10 +329,22 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
return DirKind;
}
+bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
+ return Kind == OpenACCClauseKind::Self;
+}
+
bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
return Kind == OpenACCClauseKind::Default || Kind == OpenACCClauseKind::If;
}
+ExprResult ParseOpenACCConditionalExpr(Parser &P) {
+ // FIXME: It isn't clear if the spec saying 'condition' means the same as
+ // it does in an if/while/etc (See ParseCXXCondition), however as it was
+ // written with Fortran/C in mind, we're going to assume it just means an
+ // 'expression evaluating to boolean'.
+ return P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
+}
+
bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
BalancedDelimiterTracker Parens(P, tok::l_paren,
tok::annot_pragma_openacc_end);
@@ -362,12 +375,7 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
break;
}
case OpenACCClauseKind::If: {
- // FIXME: It isn't clear if the spec saying 'condition' means the same as
- // it does in an if/while/etc (See ParseCXXCondition), however as it was
- // written with Fortran/C in mind, we're going to assume it just means an
- // 'expression evaluating to boolean'.
- ExprResult CondExpr =
- P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
+ ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
// An invalid expression can be just about anything, so just give up on
// this clause list.
if (CondExpr.isInvalid())
@@ -379,8 +387,23 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
}
return Parens.consumeClose();
+ } else if (ClauseHasOptionalParens(Kind)) {
+ if (!Parens.consumeOpen()) {
+ switch (Kind) {
+ case OpenACCClauseKind::Self: {
+ ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
+ // An invalid expression can be just about anything, so just give up on
+ // this clause list.
+ if (CondExpr.isInvalid())
+ return true;
+ break;
+ }
+ default:
+ llvm_unreachable("Not an optional parens type?");
+ }
+ Parens.consumeClose();
+ }
}
- // FIXME: Handle optional parens
return false;
}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index b247210ff6c764..11e89d420e6b08 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -236,6 +236,85 @@ void IfClause() {
for(;;){}
}
+void SyncClause() {
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self
+ for(;;){}
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self, seq
+ for(;;){}
+
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(
+ for(;;){}
+
+ // expected-error at +2{{use of undeclared identifier 'seq'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self( seq
+ for(;;){}
+
+ // expected-error at +3{{expected expression}}
+ // expected-error at +2{{use of undeclared identifier 'seq'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(, seq
+ for(;;){}
+
+ // expected-error at +2{{expected identifier}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self)
+ for(;;){}
+
+ // expected-error at +2{{expected identifier}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self) seq
+ for(;;){}
+
+ // expected-error at +2{{expected identifier}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self), seq
+ for(;;){}
+
+
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(), seq
+ for(;;){}
+
+ // expected-error at +3{{expected expression}}
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(,), seq
+ for(;;){}
+
+ // expected-error at +2{{use of undeclared identifier 'invalid_expr'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(invalid_expr), seq
+ for(;;){}
+
+ int i, j;
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(i > j
+ for(;;){}
+
+ // expected-error at +2{{use of undeclared identifier 'seq'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(i > j, seq
+ for(;;){}
+
+ // 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(1+5>3), seq
+ for(;;){}
+}
+
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine worker, vector, seq, nohost
void bar();
More information about the cfe-commits
mailing list