[clang] [OpenACC] Add 'clause' parsing infrastructure plus a few clauses (PR #75052)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 18 18:53:36 PST 2023
https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/75052
>From 0bcee977f95f87a5ccf7bc53d6cd0a5d9521d963 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 8 Dec 2023 09:18:40 -0800
Subject: [PATCH 1/4] [OpenACC] Add 'clause' parsing infrastructure plus a few
clauses
As we've now finished parsing the constructs, we're moving onto
implementing 'clause' parsing. While some are complicated and require
their own patch, the handful added here are simple to parse (that is,
they are a single identifier).
This patch adds the infrastructure to parse these and a clause-list in
its entirety. This adds some complication to how we are diagnosing
parsing errors elsewhere, so a few changes were made to better recover
from errors.
---
.../clang/Basic/DiagnosticParseKinds.td | 4 +-
clang/include/clang/Basic/OpenACCKinds.h | 13 +++
clang/lib/Parse/ParseOpenACC.cpp | 86 +++++++++++++++++--
.../ParserOpenACC/parse-cache-construct.c | 4 +-
clang/test/ParserOpenACC/parse-clauses.c | 64 ++++++++++++++
clang/test/ParserOpenACC/parse-constructs.c | 68 +++++++--------
.../test/ParserOpenACC/parse-wait-construct.c | 24 +++---
clang/test/ParserOpenACC/unimplemented.c | 6 +-
clang/test/ParserOpenACC/unimplemented.cpp | 6 +-
9 files changed, 208 insertions(+), 67 deletions(-)
create mode 100644 clang/test/ParserOpenACC/parse-clauses.c
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 6150fc36430ab1..e4b1069cde1850 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1358,11 +1358,9 @@ def err_acc_unexpected_directive
def warn_pragma_acc_unimplemented
: Warning<"OpenACC directives not yet implemented, pragma ignored">,
InGroup<SourceUsesOpenACC>;
-def warn_pragma_acc_unimplemented_clause_parsing
- : Warning<"OpenACC clause parsing not yet implemented">,
- InGroup<SourceUsesOpenACC>;
def err_acc_invalid_directive
: Error<"invalid OpenACC directive %select{%1|'%1 %2'}0">;
+def err_acc_invalid_clause : Error<"invalid OpenACC clause %0">;
def err_acc_missing_directive : Error<"expected OpenACC directive">;
def err_acc_invalid_open_paren
: Error<"expected clause-list or newline in OpenACC directive">;
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 62c0a4c1a9dea4..e907c192ed6d29 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -69,6 +69,19 @@ enum class OpenACCAtomicKind {
Capture,
Invalid,
};
+
+// Represents the kind of an OpenACC clause.
+enum class OpenACCClauseKind {
+ Finalize,
+ IfPresent,
+ Seq,
+ Independent,
+ Auto,
+ Worker,
+ Vector,
+ NoHost,
+ Invalid,
+};
} // namespace clang
#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index f7f096762e91a6..2ad296e23e8f00 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -69,6 +69,29 @@ OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) {
.Default(OpenACCDirectiveKindEx::Invalid);
}
+// Translate single-token string representations to the OpenCC Clause Kind.
+OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
+ // auto is a keyword in some language modes, so make sure we parse it
+ // correctly.
+ if (Tok.is(tok::kw_auto))
+ return OpenACCClauseKind::Auto;
+
+ if (!Tok.is(tok::identifier))
+ return OpenACCClauseKind::Invalid;
+
+ return llvm::StringSwitch<OpenACCClauseKind>(
+ Tok.getIdentifierInfo()->getName())
+ .Case("finalize", OpenACCClauseKind::Finalize)
+ .Case("if_present", OpenACCClauseKind::IfPresent)
+ .Case("seq", OpenACCClauseKind::Seq)
+ .Case("independent", OpenACCClauseKind::Independent)
+ .Case("auto", OpenACCClauseKind::Auto)
+ .Case("worker", OpenACCClauseKind::Worker)
+ .Case("vector", OpenACCClauseKind::Vector)
+ .Case("nohost", OpenACCClauseKind::NoHost)
+ .Default(OpenACCClauseKind::Invalid);
+}
+
// Since 'atomic' is effectively a compound directive, this will decode the
// second part of the directive.
OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
@@ -164,6 +187,10 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
return OpenACCDirectiveKind::Invalid;
}
+ // Consume the second name anyway, this way we can continue on without making
+ // this oddly look like a clause.
+ P.ConsumeAnyToken();
+
if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
if (!SecondTok.is(tok::identifier))
P.Diag(SecondTok, diag::err_expected) << tok::identifier;
@@ -174,8 +201,6 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
return OpenACCDirectiveKind::Invalid;
}
- P.ConsumeToken();
-
return ExtDirKind == OpenACCDirectiveKindEx::Enter
? OpenACCDirectiveKind::EnterData
: OpenACCDirectiveKind::ExitData;
@@ -208,6 +233,10 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
// introspect on the spelling before then.
if (FirstTok.isNot(tok::identifier)) {
P.Diag(FirstTok, diag::err_acc_missing_directive);
+
+ if (!FirstTok.isAnnotation())
+ P.ConsumeAnyToken();
+
return OpenACCDirectiveKind::Invalid;
}
@@ -262,12 +291,51 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
return DirKind;
}
+bool ParseOpenACCClause(Parser &P) {
+ if (!P.getCurToken().isOneOf(tok::identifier, tok::kw_auto))
+ return P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
+
+ OpenACCClauseKind Kind = getOpenACCClauseKind(P.getCurToken());
+
+ if (Kind == OpenACCClauseKind::Invalid)
+ return P.Diag(P.getCurToken(), diag::err_acc_invalid_clause)
+ << P.getCurToken().getIdentifierInfo();
+
+ // Consume the clause name.
+ P.ConsumeToken();
+
+ // FIXME: For future clauses, we need to handle parens/etc below.
+ return false;
+}
+
+// Skip until we see the end of pragma token, but don't consume it. This is us
+// just giving up on the rest of the pragma so we can continue executing. We
+// have to do this because 'SkipUntil' considers paren balancing, which isn't
+// what we want.
+void SkipUntilEndOfDirective(Parser &P) {
+ while(P.getCurToken().isNot(tok::annot_pragma_openacc_end))
+ P.ConsumeAnyToken();
+}
+
+// OpenACC 3.3, section 1.7:
+// To simplify the specification and convey appropriate constraint information,
+// 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 ParseOpenACCClauseList(Parser &P) {
- // FIXME: In the future, we'll start parsing the clauses here, but for now we
- // haven't implemented that, so just emit the unimplemented diagnostic and
- // fail reasonably.
- if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
- P.Diag(P.getCurToken(), diag::warn_pragma_acc_unimplemented_clause_parsing);
+ bool FirstClause = true;
+ while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) {
+ // Comma is optional in a clause-list.
+ if (!FirstClause && P.getCurToken().is(tok::comma))
+ P.ConsumeToken();
+ FirstClause = false;
+
+ // Recovering from a bad clause is really difficult, so we just give up on error.
+ if (ParseOpenACCClause(P)) {
+ SkipUntilEndOfDirective(P);
+ return;
+ }
+ }
}
} // namespace
@@ -499,7 +567,9 @@ void Parser::ParseOpenACCDirective() {
ParseOpenACCClauseList(*this);
Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
- SkipUntil(tok::annot_pragma_openacc_end);
+ assert(Tok.is(tok::annot_pragma_openacc_end) &&
+ "Didn't parse all OpenACC Clauses");
+ ConsumeAnnotationToken();
}
// Parse OpenACC directive on a declaration.
diff --git a/clang/test/ParserOpenACC/parse-cache-construct.c b/clang/test/ParserOpenACC/parse-cache-construct.c
index 10976627ca95ce..560f45423bc2b9 100644
--- a/clang/test/ParserOpenACC/parse-cache-construct.c
+++ b/clang/test/ParserOpenACC/parse-cache-construct.c
@@ -14,7 +14,7 @@ void func() {
for (int i = 0; i < 10; ++i) {
// expected-error at +3{{expected '('}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc cache clause list
}
@@ -25,7 +25,7 @@ void func() {
}
for (int i = 0; i < 10; ++i) {
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc cache() clause-list
}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
new file mode 100644
index 00000000000000..1e05d82906aedc
--- /dev/null
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 %s -verify -fopenacc -std=c99
+// RUNX: %clang_cc1 %s -verify -fopenacc
+// RUNX: %clang_cc1 %s -verify -fopenacc -x c++
+
+void func() {
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc enter data finalize
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc enter data finalize finalize
+
+ // expected-error at +2{{invalid OpenACC clause 'invalid'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc enter data finalize invalid
+
+ // expected-error at +2{{invalid OpenACC clause 'invalid'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc enter data finalize invalid invalid finalize
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc enter data seq finalize
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc host_data if_present
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc host_data if_present, if_present
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop seq independent auto
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop seq, independent auto
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop seq independent, auto
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc kernels loop seq independent auto
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop seq, independent auto
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel loop seq independent, auto
+
+
+ // expected-error at +2{{expected identifier}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop , seq
+
+ // expected-error at +2{{expected identifier}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop seq,
+
+}
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc routine worker, vector, seq, nohost
+void bar();
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc routine(bar) worker, vector, seq, nohost
diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c
index 83d9bd6070d41d..0bb33269bbe98f 100644
--- a/clang/test/ParserOpenACC/parse-constructs.c
+++ b/clang/test/ParserOpenACC/parse-constructs.c
@@ -7,14 +7,13 @@ void func() {
#pragma acc
for(;;){}
- // expected-error at +4{{expected OpenACC directive}}
- // expected-error at +3{{expected clause-list or newline in OpenACC directive}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +3{{expected OpenACC directive}}
+ // expected-error at +2{{invalid OpenACC clause 'whatever'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc(whatever) routine
// expected-error at +3{{expected OpenACC directive}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'routine'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc) routine
@@ -23,12 +22,12 @@ void func() {
#pragma acc invalid
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel clause list
for(;;){}
// expected-error at +3{{expected clause-list or newline in OpenACC directive}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel() clause list
for(;;){}
@@ -38,33 +37,31 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel( clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc serial clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc kernels clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc data clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc enter data clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc exit data clause list
for(;;){}
- // expected-error at +3{{invalid OpenACC directive 'enter invalid'}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC directive 'enter invalid'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc enter invalid
for(;;){}
- // expected-error at +3{{invalid OpenACC directive 'exit invalid'}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC directive 'exit invalid'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc exit invalid
for(;;){}
@@ -72,24 +69,23 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc enter
for(;;){}
- // expected-error at +3{{expected identifier}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{expected identifier}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc exit }
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc host_data clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc loop clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'invalid'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel invalid clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel loop clause list
for(;;){}
@@ -97,14 +93,14 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc parallel loop
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc serial loop clause list
for(;;){}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc serial loop
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc kernels loop clause list
for(;;){}
@@ -116,48 +112,48 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic
i = j;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'garbage'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic garbage
i = j;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'garbage'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic garbage clause list
i = j;
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic read
i = j;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic write clause list
i = i + j;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic update clause list
i++;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc atomic capture clause list
i = j++;
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc declare clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc init clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc shutdown clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc set clause list
for(;;){}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc update clause list
for(;;){}
@@ -166,7 +162,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine
void routine_func();
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine clause list
void routine_func();
@@ -175,13 +171,13 @@ void routine_func();
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine (func_name)
// expected-error at +3{{use of undeclared identifier 'func_name'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine (func_name) clause list
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine (routine_func)
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine (routine_func) clause list
diff --git a/clang/test/ParserOpenACC/parse-wait-construct.c b/clang/test/ParserOpenACC/parse-wait-construct.c
index 9b210bc7094210..8f99f4aa8f67b1 100644
--- a/clang/test/ParserOpenACC/parse-wait-construct.c
+++ b/clang/test/ParserOpenACC/parse-wait-construct.c
@@ -6,7 +6,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait clause-list
@@ -18,7 +18,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait ()
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait () clause-list
@@ -33,7 +33,7 @@ void func() {
#pragma acc wait (devnum:)
// expected-error at +3{{expected expression}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (devnum:) clause-list
@@ -48,7 +48,7 @@ void func() {
#pragma acc wait (devnum: i + j)
// expected-error at +3{{expected ':'}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (devnum: i + j) clause-list
@@ -60,7 +60,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (queues:)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (queues:) clause-list
@@ -72,7 +72,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (devnum: i + j:queues:)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (devnum: i + j:queues:) clause-list
@@ -87,7 +87,7 @@ void func() {
#pragma acc wait (queues:devnum: i + j)
// expected-error at +3{{use of undeclared identifier 'devnum'}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait (queues:devnum: i + j) clause-list
@@ -98,7 +98,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(i, j, 1+1, 3.3)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(i, j, 1+1, 3.3) clause-list
@@ -113,7 +113,7 @@ void func() {
#pragma acc wait(,)
// expected-error at +3{{expected expression}}
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(,) clause-list
@@ -131,7 +131,7 @@ void func() {
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(queues:i, j, 1+1, 3.3)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(queues:i, j, 1+1, 3.3) clause-list
@@ -141,7 +141,7 @@ void func() {
#pragma acc wait(devnum:3:i, j, 1+1, 3.3
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(devnum:3:i, j, 1+1, 3.3)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list
@@ -151,7 +151,7 @@ void func() {
#pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3)
- // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-error at +2{{invalid OpenACC clause 'clause'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) clause-list
}
diff --git a/clang/test/ParserOpenACC/unimplemented.c b/clang/test/ParserOpenACC/unimplemented.c
index 2927e685d30b56..be8e62b5811789 100644
--- a/clang/test/ParserOpenACC/unimplemented.c
+++ b/clang/test/ParserOpenACC/unimplemented.c
@@ -2,7 +2,7 @@
// Parser::ParseExternalDeclaration
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
int foo;
@@ -10,7 +10,7 @@ int foo;
struct S {
// Parser::ParseStructUnionBody
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
int foo;
@@ -19,7 +19,7 @@ struct S {
void func() {
// Parser::ParseStmtOrDeclarationAfterAttributes
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
while(0) {}
diff --git a/clang/test/ParserOpenACC/unimplemented.cpp b/clang/test/ParserOpenACC/unimplemented.cpp
index 77619c9ae6551e..6ffc84a3bc09d3 100644
--- a/clang/test/ParserOpenACC/unimplemented.cpp
+++ b/clang/test/ParserOpenACC/unimplemented.cpp
@@ -2,7 +2,7 @@
// Parser::ParseExternalDeclaration
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
int foo;
@@ -10,7 +10,7 @@ int foo;
struct S {
// Parser::ParseCXXClassMemberDeclarationWithPragmas
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
int foo;
@@ -19,7 +19,7 @@ struct S {
void func() {
// Parser::ParseStmtOrDeclarationAfterAttributes
// expected-error at +3{{invalid OpenACC directive 'havent'}}
-// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-error at +2{{invalid OpenACC clause 'implemented'}}
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc havent implemented
while(false) {}
>From c34e806bab9e093f35beab3a7bc26bcdda46f485 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Mon, 11 Dec 2023 06:49:06 -0800
Subject: [PATCH 2/4] Fix clang-format errors
---
clang/lib/Parse/ParseOpenACC.cpp | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 2ad296e23e8f00..50a8d85450f98e 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -80,16 +80,16 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
return OpenACCClauseKind::Invalid;
return llvm::StringSwitch<OpenACCClauseKind>(
- Tok.getIdentifierInfo()->getName())
- .Case("finalize", OpenACCClauseKind::Finalize)
- .Case("if_present", OpenACCClauseKind::IfPresent)
- .Case("seq", OpenACCClauseKind::Seq)
- .Case("independent", OpenACCClauseKind::Independent)
- .Case("auto", OpenACCClauseKind::Auto)
- .Case("worker", OpenACCClauseKind::Worker)
- .Case("vector", OpenACCClauseKind::Vector)
- .Case("nohost", OpenACCClauseKind::NoHost)
- .Default(OpenACCClauseKind::Invalid);
+ Tok.getIdentifierInfo()->getName())
+ .Case("finalize", OpenACCClauseKind::Finalize)
+ .Case("if_present", OpenACCClauseKind::IfPresent)
+ .Case("seq", OpenACCClauseKind::Seq)
+ .Case("independent", OpenACCClauseKind::Independent)
+ .Case("auto", OpenACCClauseKind::Auto)
+ .Case("worker", OpenACCClauseKind::Worker)
+ .Case("vector", OpenACCClauseKind::Vector)
+ .Case("nohost", OpenACCClauseKind::NoHost)
+ .Default(OpenACCClauseKind::Invalid);
}
// Since 'atomic' is effectively a compound directive, this will decode the
@@ -313,7 +313,7 @@ bool ParseOpenACCClause(Parser &P) {
// have to do this because 'SkipUntil' considers paren balancing, which isn't
// what we want.
void SkipUntilEndOfDirective(Parser &P) {
- while(P.getCurToken().isNot(tok::annot_pragma_openacc_end))
+ while (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
P.ConsumeAnyToken();
}
@@ -330,7 +330,8 @@ void ParseOpenACCClauseList(Parser &P) {
P.ConsumeToken();
FirstClause = false;
- // Recovering from a bad clause is really difficult, so we just give up on error.
+ // Recovering from a bad clause is really difficult, so we just give up on
+ // error.
if (ParseOpenACCClause(P)) {
SkipUntilEndOfDirective(P);
return;
>From 694feb4ffb23be63d512e623990d1f627c77b91e Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Wed, 13 Dec 2023 07:23:41 -0800
Subject: [PATCH 3/4] Fixes suggested by Corentin
---
clang/lib/Parse/ParseOpenACC.cpp | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 50a8d85450f98e..67325f0a286a99 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -81,14 +81,14 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
return llvm::StringSwitch<OpenACCClauseKind>(
Tok.getIdentifierInfo()->getName())
+ .Case("auto", OpenACCClauseKind::Auto)
.Case("finalize", OpenACCClauseKind::Finalize)
.Case("if_present", OpenACCClauseKind::IfPresent)
- .Case("seq", OpenACCClauseKind::Seq)
.Case("independent", OpenACCClauseKind::Independent)
- .Case("auto", OpenACCClauseKind::Auto)
- .Case("worker", OpenACCClauseKind::Worker)
- .Case("vector", OpenACCClauseKind::Vector)
.Case("nohost", OpenACCClauseKind::NoHost)
+ .Case("seq", OpenACCClauseKind::Seq)
+ .Case("vector", OpenACCClauseKind::Vector)
+ .Case("worker", OpenACCClauseKind::Worker)
.Default(OpenACCClauseKind::Invalid);
}
@@ -234,7 +234,7 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
if (FirstTok.isNot(tok::identifier)) {
P.Diag(FirstTok, diag::err_acc_missing_directive);
- if (!FirstTok.isAnnotation())
+ if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
P.ConsumeAnyToken();
return OpenACCDirectiveKind::Invalid;
@@ -291,6 +291,11 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
return DirKind;
}
+// The OpenACC Clause List is a comma or space-delimited list of clauses (see
+// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
+// really have its owner grammar and each individual one has its own definition.
+// However, they all are named with a single-identifier (or auto!) token,
+// followed in some cases by either braces or parens.
bool ParseOpenACCClause(Parser &P) {
if (!P.getCurToken().isOneOf(tok::identifier, tok::kw_auto))
return P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
>From 8b2de7c8846aeb2f0bafda8e4415605bb27ae460 Mon Sep 17 00:00:00 2001
From: Erich Keane <erich.keane at verizon.net>
Date: Mon, 18 Dec 2023 18:48:13 -0800
Subject: [PATCH 4/4] Fix code review comments
---
clang/include/clang/Basic/OpenACCKinds.h | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index e907c192ed6d29..3117d584d347b9 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -70,16 +70,27 @@ enum class OpenACCAtomicKind {
Invalid,
};
-// Represents the kind of an OpenACC clause.
+/// Represents the kind of an OpenACC clause.
enum class OpenACCClauseKind {
+ // 'finalize' clause, allowed on 'exit data' directive.
Finalize,
+ // 'if_present' clause, allowed on 'host_data' and 'update' directives.
IfPresent,
+ // 'seq' clause, allowed on 'loop' and 'routine' directives.
Seq,
+ // 'independent' clause, allowed on 'loop' directives.
Independent,
+ // 'auto' clause, allowed on 'loop' directives.
Auto,
+ // 'worker' clause, allowed on 'loop' and 'routine' directives.
Worker,
+ // 'vector' clause, allowed on 'loop' and 'routine' directives. Takes no
+ // arguments for 'routine', so the 'loop' version is not yet implemented
+ // completely.
Vector,
+ // 'nohost' clause, allowed on 'routine' directives.
NoHost,
+ // Represents an invalid clause, for the purposes of parsing.
Invalid,
};
} // namespace clang
More information about the cfe-commits
mailing list