[clang] [OpenACC] Implement initial parsing for Construct/Directive Names (PR #72661)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 17 07:16:21 PST 2023
https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/72661
>From 01fc81b37ad744a265f712b26fd6c3a85430c719 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 17 Nov 2023 06:29:35 -0800
Subject: [PATCH 1/2] [OpenACC] Implement initial parsing for
Construct/Directive Names
As the first real parsing effort for the OpenACC implementation effort,
this implements the parsing for construct/directive names. This does not
do any semantic analysis, nor any parsing for the parens for afew of the
constructs, nor any of the clauses. Those will come in a future patch.
For the time being, we warn when we hit a point that we don't implement
the parsing for either of these situations.
---
.../clang/Basic/DiagnosticParseKinds.td | 25 +-
clang/include/clang/Basic/OpenACCKinds.h | 72 ++++++
clang/include/clang/Parse/Parser.h | 6 +-
.../clang/Parse/RAIIObjectsForParser.h | 19 ++
clang/lib/Parse/ParseDecl.cpp | 2 +-
clang/lib/Parse/ParseDeclCXX.cpp | 2 +-
clang/lib/Parse/ParseOpenACC.cpp | 232 +++++++++++++++++-
clang/lib/Parse/Parser.cpp | 7 +-
clang/test/ParserOpenACC/parse-constructs.c | 148 +++++++++++
clang/test/ParserOpenACC/unimplemented.c | 6 +-
clang/test/ParserOpenACC/unimplemented.cpp | 6 +-
11 files changed, 504 insertions(+), 21 deletions(-)
create mode 100644 clang/include/clang/Basic/OpenACCKinds.h
create mode 100644 clang/test/ParserOpenACC/parse-constructs.c
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index c3d06053caa5eea..54ae536e9cf7935 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1343,13 +1343,30 @@ def err_openclcxx_virtual_function : Error<
"virtual functions are not supported in C++ for OpenCL">;
// OpenACC Support.
-def warn_pragma_acc_ignored : Warning<
- "unexpected '#pragma acc ...' in program">, InGroup<SourceUsesOpenACC>, DefaultIgnore;
-def err_acc_unexpected_directive : Error<
- "unexpected OpenACC directive %select{|'#pragma acc %1'}0">;
+def warn_pragma_acc_ignored
+ : Warning<"unexpected '#pragma acc ...' in program">,
+ InGroup<SourceUsesOpenACC>,
+ DefaultIgnore;
+def err_acc_unexpected_directive
+ : Error<"unexpected OpenACC directive %select{|'#pragma acc %1'}0">;
def warn_pragma_acc_unimplemented
: Warning<"OpenACC directives not yet implemented, pragma ignored">,
InGroup<SourceUsesOpenACC>;
+def warn_pragma_acc_unimplemented_construct_parens
+ : Warning<
+ "OpenACC %select{'cache' 'var-list'|'wait-argument'|'routine-name'}0 "
+ "parsing not yet implemented">,
+ 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_atomic_clause
+ : Error<"invalid OpenACC 'atomic-clause' '%0'; expected 'read', 'write', "
+ "'update', or 'capture'">;
+def err_acc_invalid_open_paren
+ : Error<"expected clause-list or newline in pragma directive">;
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
new file mode 100644
index 000000000000000..8a901d96bec5207
--- /dev/null
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -0,0 +1,72 @@
+//===--- OpenACCKinds.h - OpenACC Enums -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines some OpenACC-specific enums and functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENACCKINDS_H
+#define LLVM_CLANG_BASIC_OPENACCKINDS_H
+
+namespace clang {
+// Represents the Construct/Directive kind of a pragma directive. Note the
+// OpenACC standard is inconsistent between calling these Construct vs
+// Directive, but we're calling it a Directive to be consistent with OpenMP.
+enum class OpenACCDirectiveKind {
+ // Compute Constructs.
+ Parallel,
+ Serial,
+ Kernels,
+
+ // Data Environment. "enter data" and "exit data" are also referred to in the
+ // Executable Directives section, but just as a back reference to the Data
+ // Environment.
+ Data,
+ EnterData,
+ ExitData,
+ HostData,
+
+ // Misc.
+ Loop,
+ Cache,
+
+ // Combined Constructs.
+ ParallelLoop,
+ SerialLoop,
+ KernelsLoop,
+
+ // Atomic Construct. The OpenACC standard considers these as a single
+ // construct, however the atomic-clause (read, write, update, capture) are
+ // important for legalization of the application of this to statements/blocks.
+ AtomicRead,
+ AtomicWrite,
+ AtomicUpdate,
+ AtomicCapture,
+
+ // Declare Directive.
+ Declare,
+
+ // Executable Directives. "wait" is first referred to here, but ends up being
+ // in its own section after "routine".
+ Init,
+ Shutdown,
+ Set,
+ Update,
+ Wait,
+
+ // Procedure Calls in Compute Regions.
+ Routine,
+
+ // Invalid.
+ Invalid,
+};
+}
+
+
+#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 4631e9a4679c435..d20a26dbf2562a7 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -53,6 +53,7 @@ namespace clang {
class Parser : public CodeCompletionHandler {
friend class ColonProtectionRAIIObject;
friend class ParsingOpenMPDirectiveRAII;
+ friend class ParsingOpenACCDirectiveRAII;
friend class InMessageExpressionRAIIObject;
friend class OffsetOfStateRAIIObject;
friend class PoisonSEHIdentifiersRAIIObject;
@@ -230,6 +231,9 @@ class Parser : public CodeCompletionHandler {
/// Parsing OpenMP directive mode.
bool OpenMPDirectiveParsing = false;
+ /// Parsing OpenACC directive mode.
+ bool OpenACCDirectiveParsing = false;
+
/// When true, we are directly inside an Objective-C message
/// send expression.
///
@@ -3531,7 +3535,7 @@ class Parser : public CodeCompletionHandler {
/// Placeholder for now, should just ignore the directives after emitting a
/// diagnostic. Eventually will be split into a few functions to parse
/// different situations.
- DeclGroupPtrTy ParseOpenACCDirective();
+ DeclGroupPtrTy ParseOpenACCDirectiveDecl();
StmtResult ParseOpenACCDirectiveStmt();
private:
diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h
index cb525c9d0edd6bc..e1626a7870bb7ae 100644
--- a/clang/include/clang/Parse/RAIIObjectsForParser.h
+++ b/clang/include/clang/Parse/RAIIObjectsForParser.h
@@ -309,6 +309,25 @@ namespace clang {
~ParsingOpenMPDirectiveRAII() { restore(); }
};
+ /// Activates OpenACC parsing mode to preseve OpenACC specific annotation
+ /// tokens.
+ class ParsingOpenACCDirectiveRAII {
+ Parser &P;
+ bool OldVal;
+
+ public:
+ ParsingOpenACCDirectiveRAII(Parser &P, bool Value = true)
+ : P(P), OldVal(P.OpenACCDirectiveParsing) {
+ P.OpenACCDirectiveParsing = Value;
+ }
+
+ /// This can be used to restore the state early, before the dtor
+ /// is run.
+ void restore() { P.OpenMPDirectiveParsing = OldVal; }
+
+ ~ParsingOpenACCDirectiveRAII() { restore(); }
+ };
+
/// RAII object that makes '>' behave either as an operator
/// or as the closing angle bracket for a template argument list.
class GreaterThanIsOperatorScope {
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index d86f477b4c9ff7a..8cb5b09fd3b0fa6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4735,7 +4735,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
}
if (Tok.is(tok::annot_pragma_openacc)) {
- ParseOpenACCDirective();
+ ParseOpenACCDirectiveDecl();
continue;
}
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e12215d74bcc8ed..d9125955fda2783 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3430,7 +3430,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
return ParseOpenMPDeclarativeDirectiveWithExtDecl(
AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl);
case tok::annot_pragma_openacc:
- return ParseOpenACCDirective();
+ return ParseOpenACCDirectiveDecl();
default:
if (tok::isPragmaAnnotation(Tok.getKind())) {
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 2fba6cd2805cf97..ed4ad440b9972b6 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -10,18 +10,240 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Basic/OpenACCKinds.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
+#include "clang/Parse/RAIIObjectsForParser.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
using namespace clang;
+using namespace llvm;
+
+namespace {
+// An enum that contains the extended 'partial' parsed variants. This type
+// should never escape the initial parse functionality, but is useful for
+// simplifying the implementation.
+enum class OpenACCDirectiveKindEx {
+ Invalid = static_cast<int>(OpenACCDirectiveKind::Invalid),
+ // 'enter data' and 'exit data'
+ Enter,
+ Exit,
+ // 'atomic read', 'atomic write', 'atomic update', and 'atomic capture'.
+ Atomic,
+};
+
+// Translate single-token string representations to the OpenACC Directive Kind.
+// This doesn't completely comprehend 'Compound Constructs' (as it just
+// identifies the first token), and doesn't fully handle 'enter data', 'exit
+// data', nor any of the 'atomic' variants, just the first token of each. So
+// this should only be used by `ParseOpenACCDirectiveKind`.
+OpenACCDirectiveKindEx GetOpenACCDirectiveKind(StringRef Name) {
+ OpenACCDirectiveKind DirKind =
+ llvm::StringSwitch<OpenACCDirectiveKind>(Name)
+ .Case("parallel", OpenACCDirectiveKind::Parallel)
+ .Case("serial", OpenACCDirectiveKind::Serial)
+ .Case("kernels", OpenACCDirectiveKind::Kernels)
+ .Case("data", OpenACCDirectiveKind::Data)
+ .Case("host_data", OpenACCDirectiveKind::HostData)
+ .Case("loop", OpenACCDirectiveKind::Loop)
+ .Case("cache", OpenACCDirectiveKind::Cache)
+ .Case("declare", OpenACCDirectiveKind::Declare)
+ .Case("init", OpenACCDirectiveKind::Init)
+ .Case("shutdown", OpenACCDirectiveKind::Shutdown)
+ .Case("set", OpenACCDirectiveKind::Shutdown)
+ .Case("update", OpenACCDirectiveKind::Update)
+ .Case("wait", OpenACCDirectiveKind::Wait)
+ .Case("routine", OpenACCDirectiveKind::Routine)
+ .Default(OpenACCDirectiveKind::Invalid);
+
+ if (DirKind != OpenACCDirectiveKind::Invalid)
+ return static_cast<OpenACCDirectiveKindEx>(DirKind);
+
+ return llvm::StringSwitch<OpenACCDirectiveKindEx>(Name)
+ .Case("enter", OpenACCDirectiveKindEx::Enter)
+ .Case("exit", OpenACCDirectiveKindEx::Exit)
+ .Case("atomic", OpenACCDirectiveKindEx::Atomic)
+ .Default(OpenACCDirectiveKindEx::Invalid);
+}
+
+// "enter data" and "exit data" are permitted as their own constructs. Handle
+// these, knowing the previous token is either 'enter' or 'exit'. The current
+// token should be the one after the "enter" or "exit".
+OpenACCDirectiveKind
+ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
+ StringRef FirstTokSpelling,
+ OpenACCDirectiveKindEx ExtDirKind) {
+ Token SecondTok = P.getCurToken();
+ std::string SecondTokSpelling = P.getPreprocessor().getSpelling(SecondTok);
+
+ if (SecondTokSpelling != "data") {
+ P.Diag(FirstTok, diag::err_acc_invalid_directive)
+ << 1 << FirstTokSpelling << SecondTokSpelling;
+ return OpenACCDirectiveKind::Invalid;
+ }
+
+ P.ConsumeToken();
+ return ExtDirKind == OpenACCDirectiveKindEx::Enter
+ ? OpenACCDirectiveKind::EnterData
+ : OpenACCDirectiveKind::ExitData;
+}
+
+OpenACCDirectiveKind ParseOpenACCAtomicDirective(Parser &P) {
+ Token AtomicClauseToken = P.getCurToken();
+ std::string AtomicClauseSpelling =
+ P.getPreprocessor().getSpelling(AtomicClauseToken);
+
+ OpenACCDirectiveKind DirKind =
+ llvm::StringSwitch<OpenACCDirectiveKind>(AtomicClauseSpelling)
+ .Case("read", OpenACCDirectiveKind::AtomicRead)
+ .Case("write", OpenACCDirectiveKind::AtomicWrite)
+ .Case("update", OpenACCDirectiveKind::AtomicUpdate)
+ .Case("capture", OpenACCDirectiveKind::AtomicCapture)
+ .Default(OpenACCDirectiveKind::Invalid);
+
+ if (DirKind == OpenACCDirectiveKind::Invalid)
+ P.Diag(AtomicClauseToken, diag::err_acc_invalid_atomic_clause)
+ << AtomicClauseSpelling;
+
+ P.ConsumeToken();
+ return DirKind;
+}
+
+// Parse and consume the tokens for OpenACC Directive/Construct kinds.
+OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
+ Token FirstTok = P.getCurToken();
+ P.ConsumeToken();
+ std::string FirstTokSpelling = P.getPreprocessor().getSpelling(FirstTok);
+
+ OpenACCDirectiveKindEx ExDirKind = GetOpenACCDirectiveKind(FirstTokSpelling);
+
+ Token SecondTok = P.getCurToken();
+ // Go through the Extended kinds to see if we can convert this to the
+ // non-Extended kinds, and handle invalid.
+ switch (ExDirKind) {
+ case OpenACCDirectiveKindEx::Invalid:
+ P.Diag(FirstTok, diag::err_acc_invalid_directive) << 0 << FirstTokSpelling;
+ return OpenACCDirectiveKind::Invalid;
+ case OpenACCDirectiveKindEx::Enter:
+ case OpenACCDirectiveKindEx::Exit:
+ return ParseOpenACCEnterExitDataDirective(P, FirstTok, FirstTokSpelling,
+ ExDirKind);
+ case OpenACCDirectiveKindEx::Atomic:
+ return ParseOpenACCAtomicDirective(P);
+ }
+
+ // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any
+ // other attempt at a combined constructwill be diagnosed as an invalid
+ // clause.
+
+ switch (static_cast<OpenACCDirectiveKind>(ExDirKind)) {
+ default:
+ break;
+ case OpenACCDirectiveKind::Parallel:
+ if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+ P.ConsumeToken();
+ return OpenACCDirectiveKind::ParallelLoop;
+ }
+ break;
+ case OpenACCDirectiveKind::Serial:
+ if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+ P.ConsumeToken();
+ return OpenACCDirectiveKind::SerialLoop;
+ }
+ break;
+ case OpenACCDirectiveKind::Kernels:
+ if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+ P.ConsumeToken();
+ return OpenACCDirectiveKind::KernelsLoop;
+ }
+ break;
+ }
+
+ return static_cast<OpenACCDirectiveKind>(ExDirKind);
+}
+
+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);
+}
+
+void ParseOpenACCDirective(Parser &P) {
+ OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(P);
+
+ if (DirKind == OpenACCDirectiveKind::Invalid) {
+ P.SkipUntil(tok::annot_pragma_openacc_end);
+ return;
+ }
+
+ // We've successfully parsed the construct/directive name, a few require
+ // special parsing which we will attempt, then revert to clause parsing.
+ BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openacc_end);
+
+ // Before we can parse clauses, there are a few directives that have special
+ // cases that need parsing before clauses:
+ //
+ // 1- 'cache' doesn't take clauses, just a 'var list'.
+ // 2- 'wait' has an optional wait-argument.
+ // 3- 'routine' takes an optional 'name' before the clause list.
+ //
+ // As these are not implemented, diagnose, and continue.
+ if (!T.consumeOpen()) {
+ switch (DirKind) {
+ default:
+ P.Diag(T.getOpenLocation(), diag::err_acc_invalid_open_paren);
+ break;
+ case OpenACCDirectiveKind::Cache:
+ P.Diag(T.getOpenLocation(),
+ diag::warn_pragma_acc_unimplemented_construct_parens)
+ << 0;
+ break;
+ case OpenACCDirectiveKind::Wait:
+ P.Diag(T.getOpenLocation(),
+ diag::warn_pragma_acc_unimplemented_construct_parens)
+ << 1;
+ break;
+ case OpenACCDirectiveKind::Routine:
+ P.Diag(T.getOpenLocation(),
+ diag::warn_pragma_acc_unimplemented_construct_parens)
+ << 2;
+ break;
+ }
+ T.skipToEnd();
+ }
+
+ // Parses the list of clauses, if present.
+ ParseOpenACCClauseList(P);
+
+ P.Diag(P.getCurToken(), diag::warn_pragma_acc_unimplemented);
+ P.SkipUntil(tok::annot_pragma_openacc_end);
+}
+
+} // namespace
+
+// Parse OpenACC directive on a declaration.
+Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
+ assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
+
+ ParsingOpenACCDirectiveRAII DirScope(*this);
+ ConsumeAnnotationToken();
+
+ ParseOpenACCDirective(*this);
-Parser::DeclGroupPtrTy Parser::ParseOpenACCDirective() {
- Diag(Tok, diag::warn_pragma_acc_unimplemented);
- SkipUntil(tok::annot_pragma_openacc_end);
return nullptr;
}
+
+// Parse OpenACC Directive on a Statement.
StmtResult Parser::ParseOpenACCDirectiveStmt() {
- Diag(Tok, diag::warn_pragma_acc_unimplemented);
- SkipUntil(tok::annot_pragma_openacc_end);
+ assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
+
+ ParsingOpenACCDirectiveRAII DirScope(*this);
+ ConsumeAnnotationToken();
+
+ ParseOpenACCDirective(*this);
+
return StmtEmpty();
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 41b74624bf1b765..1baeb2aeb021faa 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -320,8 +320,9 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
break;
case tok::annot_pragma_openacc:
case tok::annot_pragma_openacc_end:
- // FIXME: Like OpenMP above, we should not be doing this if we're parsing
- // an OpenACC Directive.
+ // Stop before an OpenACC pragma boundary.
+ if (OpenACCDirectiveParsing)
+ return false;
ConsumeAnnotationToken();
break;
case tok::annot_module_begin:
@@ -858,7 +859,7 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
}
case tok::annot_pragma_openacc:
- return ParseOpenACCDirective();
+ return ParseOpenACCDirectiveDecl();
case tok::annot_pragma_ms_pointers_to_members:
HandlePragmaMSPointersToMembers();
return nullptr;
diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c
new file mode 100644
index 000000000000000..8e7f84d3f0d424e
--- /dev/null
+++ b/clang/test/ParserOpenACC/parse-constructs.c
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 %s -verify -fopenacc
+
+
+
+void func() {
+
+ //expected-error at +1{{invalid OpenACC directive 'invalid'}}
+#pragma acc invalid
+ for(;;){}
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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 pragma directive}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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-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-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-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc data clause list
+ for(;;){}
+ // expected-error at +1{{invalid OpenACC directive 'enter invalid'}}
+#pragma acc enter invalid clause list
+ for(;;){}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc exit data clause list
+ for(;;){}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop clause list
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc cache
+ for(;;){}
+ // expected-warning at +2{{OpenACC 'cache' 'var-list' parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc cache(var,list)
+ for(;;){}
+ // expected-warning at +2{{OpenACC 'cache' 'var-list' parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc cache(readonly:var,list)
+ for(;;){}
+ // expected-warning at +3{{OpenACC 'cache' 'var-list' parsing not yet implemented}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc cache(readonly:var,list) invalid clause list
+ for(;;){}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel loop clause list
+ for(;;){}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop clause list
+ for(;;){}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc kernels loop clause list
+ for(;;){}
+
+ int i = 0, j = 0, k = 0;
+ // expected-error at +1{{invalid OpenACC 'atomic-clause' 'garbage'; expected 'read', 'write', 'update', or 'capture'}}
+#pragma acc atomic garbage
+ i = j;
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc atomic read
+ i = j;
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc atomic write
+ i = i + j;
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc atomic update
+ i++;
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc atomic capture
+ i = j++;
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc atomic capture invalid clause list
+ i = j++;
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // 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-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-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-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-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update clause list
+ for(;;){}
+}
+
+// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc routine clause list
+void routine_func(void ) {}
+
+ // expected-warning at +3{{OpenACC 'routine-name' parsing not yet implemented}}
+// expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc routine(routine_func) clause list
+
+void func2() {
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc wait clause-list
+ for(;;){}
+ // expected-warning at +3{{OpenACC 'wait-argument' parsing not yet implemented}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc wait(1::) clause-list
+ for(;;){}
+}
diff --git a/clang/test/ParserOpenACC/unimplemented.c b/clang/test/ParserOpenACC/unimplemented.c
index c1228c8f2b97fc5..1248973e5ecc52d 100644
--- a/clang/test/ParserOpenACC/unimplemented.c
+++ b/clang/test/ParserOpenACC/unimplemented.c
@@ -1,20 +1,20 @@
// RUN: %clang_cc1 %s -verify -fopenacc
// Parser::ParseExternalDeclaration
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
int foo;
struct S {
// Parser::ParseStructUnionBody
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
int foo;
};
void func() {
// Parser::ParseStmtOrDeclarationAfterAttributes
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
while(0) {}
}
diff --git a/clang/test/ParserOpenACC/unimplemented.cpp b/clang/test/ParserOpenACC/unimplemented.cpp
index 095cbf570a41a06..0266d6bf36768e8 100644
--- a/clang/test/ParserOpenACC/unimplemented.cpp
+++ b/clang/test/ParserOpenACC/unimplemented.cpp
@@ -1,20 +1,20 @@
// RUN: %clang_cc1 %s -verify -fopenacc
// Parser::ParseExternalDeclaration
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
int foo;
struct S {
// Parser::ParseCXXClassMemberDeclarationWithPragmas
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
int foo;
};
void func() {
// Parser::ParseStmtOrDeclarationAfterAttributes
-// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+// expected-error at +1{{invalid OpenACC directive 'not'}}
#pragma acc not yet implemented
while(false) {}
}
>From b76ab0fe3aa825c034a3503a953b600f4a872c65 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 17 Nov 2023 07:14:22 -0800
Subject: [PATCH 2/2] Clang Format fix
---
clang/include/clang/Basic/OpenACCKinds.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 8a901d96bec5207..0197f3bcaa4cfb9 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -66,7 +66,6 @@ enum class OpenACCDirectiveKind {
// Invalid.
Invalid,
};
-}
-
+} // namespace clang
#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
More information about the cfe-commits
mailing list