[clang] 6263de9 - [OpenACC] Implement 'modifier-list' sema/AST
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 4 12:32:39 PDT 2025
Author: erichkeane
Date: 2025-04-04T12:32:33-07:00
New Revision: 6263de90df7f58c8b98475024d5eef102e10a372
URL: https://github.com/llvm/llvm-project/commit/6263de90df7f58c8b98475024d5eef102e10a372
DIFF: https://github.com/llvm/llvm-project/commit/6263de90df7f58c8b98475024d5eef102e10a372.diff
LOG: [OpenACC] Implement 'modifier-list' sema/AST
OpenACC 3.3-NEXT has changed the way tags for copy, copyin, copyout, and
create clauses are specified, and end up adding a few extras, and
permits them as a list. This patch encodes these as bitmask enum so
they can be stored succinctly, but still diagnose reasonably.
Added:
Modified:
clang/include/clang/AST/OpenACCClause.h
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/OpenACCKinds.h
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/SemaOpenACC.h
clang/lib/AST/OpenACCClause.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Parse/ParseOpenACC.cpp
clang/lib/Sema/SemaOpenACC.cpp
clang/lib/Sema/SemaOpenACCClause.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/AST/ast-print-openacc-combined-construct.cpp
clang/test/AST/ast-print-openacc-compute-construct.cpp
clang/test/AST/ast-print-openacc-data-construct.cpp
clang/test/AST/ast-print-openacc-declare-construct.cpp
clang/test/ParserOpenACC/parse-clauses.c
clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
clang/test/SemaOpenACC/combined-construct-copy-clause.c
clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
clang/test/SemaOpenACC/combined-construct-copyin-clause.c
clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
clang/test/SemaOpenACC/combined-construct-copyout-clause.c
clang/test/SemaOpenACC/combined-construct-create-ast.cpp
clang/test/SemaOpenACC/combined-construct-create-clause.c
clang/test/SemaOpenACC/compute-construct-copy-clause.c
clang/test/SemaOpenACC/compute-construct-copyin-clause.c
clang/test/SemaOpenACC/compute-construct-copyout-clause.c
clang/test/SemaOpenACC/compute-construct-create-clause.c
clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
clang/test/SemaOpenACC/data-construct-copy-ast.cpp
clang/test/SemaOpenACC/data-construct-copy-clause.c
clang/test/SemaOpenACC/data-construct-copyin-ast.cpp
clang/test/SemaOpenACC/data-construct-copyin-clause.c
clang/test/SemaOpenACC/data-construct-copyout-ast.cpp
clang/test/SemaOpenACC/data-construct-copyout-clause.c
clang/test/SemaOpenACC/data-construct-create-ast.cpp
clang/test/SemaOpenACC/data-construct-create-clause.c
clang/test/SemaOpenACC/declare-construct-ast.cpp
clang/test/SemaOpenACC/declare-construct.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 4c5fe03a34361..b3a5746af7cb0 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -1087,11 +1087,13 @@ class OpenACCCopyClause final
: public OpenACCClauseWithVarList,
private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
friend TrailingObjects;
+ OpenACCModifierKind Modifiers;
OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
- SourceLocation LParenLoc, ArrayRef<Expr *> VarList,
- SourceLocation EndLoc)
- : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc) {
+ SourceLocation LParenLoc, OpenACCModifierKind Mods,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
+ Modifiers(Mods) {
assert((Spelling == OpenACCClauseKind::Copy ||
Spelling == OpenACCClauseKind::PCopy ||
Spelling == OpenACCClauseKind::PresentOrCopy) &&
@@ -1110,20 +1112,23 @@ class OpenACCCopyClause final
static OpenACCCopyClause *
Create(const ASTContext &C, OpenACCClauseKind Spelling,
SourceLocation BeginLoc, SourceLocation LParenLoc,
- ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc);
+
+ OpenACCModifierKind getModifierList() const { return Modifiers; }
};
class OpenACCCopyInClause final
: public OpenACCClauseWithVarList,
private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
friend TrailingObjects;
- bool IsReadOnly;
+ OpenACCModifierKind Modifiers;
OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
- SourceLocation LParenLoc, bool IsReadOnly,
+ SourceLocation LParenLoc, OpenACCModifierKind Mods,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
- IsReadOnly(IsReadOnly) {
+ Modifiers(Mods) {
assert((Spelling == OpenACCClauseKind::CopyIn ||
Spelling == OpenACCClauseKind::PCopyIn ||
Spelling == OpenACCClauseKind::PresentOrCopyIn) &&
@@ -1139,24 +1144,25 @@ class OpenACCCopyInClause final
C->getClauseKind() == OpenACCClauseKind::PCopyIn ||
C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn;
}
- bool isReadOnly() const { return IsReadOnly; }
+ OpenACCModifierKind getModifierList() const { return Modifiers; }
static OpenACCCopyInClause *
Create(const ASTContext &C, OpenACCClauseKind Spelling,
- SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly,
- ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+ SourceLocation BeginLoc, SourceLocation LParenLoc,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc);
};
class OpenACCCopyOutClause final
: public OpenACCClauseWithVarList,
private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
friend TrailingObjects;
- bool IsZero;
+ OpenACCModifierKind Modifiers;
OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
- SourceLocation LParenLoc, bool IsZero,
+ SourceLocation LParenLoc, OpenACCModifierKind Mods,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
- IsZero(IsZero) {
+ Modifiers(Mods) {
assert((Spelling == OpenACCClauseKind::CopyOut ||
Spelling == OpenACCClauseKind::PCopyOut ||
Spelling == OpenACCClauseKind::PresentOrCopyOut) &&
@@ -1172,24 +1178,25 @@ class OpenACCCopyOutClause final
C->getClauseKind() == OpenACCClauseKind::PCopyOut ||
C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut;
}
- bool isZero() const { return IsZero; }
+ OpenACCModifierKind getModifierList() const { return Modifiers; }
static OpenACCCopyOutClause *
Create(const ASTContext &C, OpenACCClauseKind Spelling,
- SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
- ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+ SourceLocation BeginLoc, SourceLocation LParenLoc,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc);
};
class OpenACCCreateClause final
: public OpenACCClauseWithVarList,
private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
friend TrailingObjects;
- bool IsZero;
+ OpenACCModifierKind Modifiers;
OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
- SourceLocation LParenLoc, bool IsZero,
+ SourceLocation LParenLoc, OpenACCModifierKind Mods,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
- IsZero(IsZero) {
+ Modifiers(Mods) {
assert((Spelling == OpenACCClauseKind::Create ||
Spelling == OpenACCClauseKind::PCreate ||
Spelling == OpenACCClauseKind::PresentOrCreate) &&
@@ -1205,11 +1212,12 @@ class OpenACCCreateClause final
C->getClauseKind() == OpenACCClauseKind::PCreate ||
C->getClauseKind() == OpenACCClauseKind::PresentOrCreate;
}
- bool isZero() const { return IsZero; }
+ OpenACCModifierKind getModifierList() const { return Modifiers; }
static OpenACCCreateClause *
Create(const ASTContext &C, OpenACCClauseKind Spelling,
- SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
- ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+ SourceLocation BeginLoc, SourceLocation LParenLoc,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc);
};
class OpenACCReductionClause final
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 954f538e15026..f46e7fed28794 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1458,6 +1458,9 @@ def err_acc_invalid_reduction_operator
: Error<"invalid reduction operator, expected '+', '*', 'max', 'min', "
"'&', '|', '^', '&&', or '||'">;
def err_acc_incorrect_bind_arg : Error<"expected identifier or string literal">;
+def err_acc_modifier
+ : Error<"%enum_select<ACCModifier>{%Unknown{unknown}|%Duplicate{duplicate}}"
+ "0 modifier %1 in OpenACC modifier-list on '%2' clause">;
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dc98ceadd23ca..393bfecf9a36b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13055,6 +13055,8 @@ def warn_acc_confusing_routine_name
InGroup<DiagGroup<"openacc-confusing-routine-name">>;
def err_acc_decl_for_routine
: Error<"expected function or lambda declaration for 'routine' construct">;
+def err_acc_invalid_modifier
+ : Error<"OpenACC '%0' modifier not valid on '%1' clause">;
// AMDGCN builtins diagnostics
def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">;
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index c2d7732123ef2..652831e23a758 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -15,10 +15,13 @@
#define LLVM_CLANG_BASIC_OPENACCKINDS_H
#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
// 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.
@@ -619,6 +622,74 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
OpenACCGangKind Op) {
return printOpenACCGangKind(Out, Op);
}
+
+// Represents the 'modifier' of a 'modifier-list', as applied to copy, copyin,
+// copyout, and create. Implemented as a 'bitmask'
+enum class OpenACCModifierKind : uint8_t {
+ Invalid = 0,
+ Always = 1 << 0,
+ AlwaysIn = 1 << 1,
+ AlwaysOut = 1 << 2,
+ Readonly = 1 << 3,
+ Zero = 1 << 4,
+ LLVM_MARK_AS_BITMASK_ENUM(Zero)
+};
+
+inline bool isOpenACCModifierBitSet(OpenACCModifierKind List,
+ OpenACCModifierKind Bit) {
+ return (List & Bit) != OpenACCModifierKind::Invalid;
+}
+
+template <typename StreamTy>
+inline StreamTy &printOpenACCModifierKind(StreamTy &Out,
+ OpenACCModifierKind Mods) {
+ if (Mods == OpenACCModifierKind::Invalid)
+ return Out << "<invalid>";
+
+ bool First = true;
+
+ if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Always)) {
+ Out << "always";
+ First = false;
+ }
+
+ if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::AlwaysIn)) {
+ if (!First)
+ Out << ", ";
+ Out << "alwaysin";
+ First = false;
+ }
+
+ if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::AlwaysOut)) {
+ if (!First)
+ Out << ", ";
+ Out << "alwaysout";
+ First = false;
+ }
+
+ if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Readonly)) {
+ if (!First)
+ Out << ", ";
+ Out << "readonly";
+ First = false;
+ }
+
+ if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Zero)) {
+ if (!First)
+ Out << ", ";
+ Out << "zero";
+ First = false;
+ }
+ return Out;
+}
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
+ OpenACCModifierKind Op) {
+ return printOpenACCModifierKind(Out, Op);
+}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
+ OpenACCModifierKind Op) {
+ return printOpenACCModifierKind(Out, Op);
+}
} // namespace clang
#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 5770692c42f13..53da6269a3b11 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3769,6 +3769,8 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseOpenACCIDExpression();
/// Parses the variable list for the `cache` construct.
OpenACCCacheParseInfo ParseOpenACCCacheVarList();
+ /// Parses the 'modifier-list' for copy, copyin, copyout, create.
+ OpenACCModifierKind tryParseModifierList(OpenACCClauseKind CK);
using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
/// Parses a single variable in a variable list for OpenACC.
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index 18d92e62d71a7..4c3a13a3b044f 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -238,8 +238,7 @@ class SemaOpenACC : public SemaBase {
struct VarListDetails {
SmallVector<Expr *> VarList;
- bool IsReadOnly;
- bool IsZero;
+ OpenACCModifierKind ModifierKind;
};
struct WaitDetails {
@@ -451,12 +450,10 @@ class SemaOpenACC : public SemaBase {
return const_cast<OpenACCParsedClause *>(this)->getVarList();
}
- bool isReadOnly() const {
- return std::get<VarListDetails>(Details).IsReadOnly;
+ OpenACCModifierKind getModifierList() const {
+ return std::get<VarListDetails>(Details).ModifierKind;
}
- bool isZero() const { return std::get<VarListDetails>(Details).IsZero; }
-
bool isForce() const {
assert(ClauseKind == OpenACCClauseKind::Collapse &&
"Only 'collapse' has a force tag");
@@ -552,8 +549,8 @@ class SemaOpenACC : public SemaBase {
Details = GangDetails{std::move(GKs), std::move(IntExprs)};
}
- void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
- bool IsZero) {
+ void setVarListDetails(ArrayRef<Expr *> VarList,
+ OpenACCModifierKind ModKind) {
assert((ClauseKind == OpenACCClauseKind::Private ||
ClauseKind == OpenACCClauseKind::NoCreate ||
ClauseKind == OpenACCClauseKind::Present ||
@@ -582,23 +579,25 @@ class SemaOpenACC : public SemaBase {
DirKind == OpenACCDirectiveKind::Update) ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
- assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
+ assert((ModKind == OpenACCModifierKind::Invalid ||
+ ClauseKind == OpenACCClauseKind::Copy ||
+ ClauseKind == OpenACCClauseKind::PCopy ||
+ ClauseKind == OpenACCClauseKind::PresentOrCopy ||
+ ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
- ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
- "readonly: tag only valid on copyin");
- assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
+ ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
+ ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
- "zero: tag only valid on copyout/create");
- Details =
- VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
+ "Modifier Kind only valid on copy, copyin, copyout, create");
+ Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
}
- void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
- bool IsZero) {
+ void setVarListDetails(llvm::SmallVector<Expr *> &&VarList,
+ OpenACCModifierKind ModKind) {
assert((ClauseKind == OpenACCClauseKind::Private ||
ClauseKind == OpenACCClauseKind::NoCreate ||
ClauseKind == OpenACCClauseKind::Present ||
@@ -627,18 +626,21 @@ class SemaOpenACC : public SemaBase {
DirKind == OpenACCDirectiveKind::Update) ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
- assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
+ assert((ModKind == OpenACCModifierKind::Invalid ||
+ ClauseKind == OpenACCClauseKind::Copy ||
+ ClauseKind == OpenACCClauseKind::PCopy ||
+ ClauseKind == OpenACCClauseKind::PresentOrCopy ||
+ ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
- ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
- "readonly: tag only valid on copyin");
- assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
+ ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
+ ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
- "zero: tag only valid on copyout/create");
- Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
+ "Modifier Kind only valid on copy, copyin, copyout, create");
+ Details = VarListDetails{std::move(VarList), ModKind};
}
void setReductionDetails(OpenACCReductionOperator Op,
@@ -826,7 +828,8 @@ class SemaOpenACC : public SemaBase {
// Checking for the arguments specific to the declare-clause that need to be
// checked during both phases of template translation.
- bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause);
+ bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
+ OpenACCModifierKind Mods);
ExprResult ActOnRoutineName(Expr *RoutineName);
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index ab76e6dffa0ff..d7cbb51335359 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -434,11 +434,12 @@ OpenACCDeviceClause *OpenACCDeviceClause::Create(const ASTContext &C,
OpenACCCopyClause *
OpenACCCopyClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
SourceLocation BeginLoc, SourceLocation LParenLoc,
- ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc) {
void *Mem =
C.Allocate(OpenACCCopyClause::totalSizeToAlloc<Expr *>(VarList.size()));
return new (Mem)
- OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, VarList, EndLoc);
+ OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, Mods, VarList, EndLoc);
}
OpenACCLinkClause *OpenACCLinkClause::Create(const ASTContext &C,
@@ -463,34 +464,34 @@ OpenACCDeviceResidentClause *OpenACCDeviceResidentClause::Create(
OpenACCCopyInClause *
OpenACCCopyInClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
SourceLocation BeginLoc, SourceLocation LParenLoc,
- bool IsReadOnly, ArrayRef<Expr *> VarList,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
SourceLocation EndLoc) {
void *Mem =
C.Allocate(OpenACCCopyInClause::totalSizeToAlloc<Expr *>(VarList.size()));
- return new (Mem) OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc,
- IsReadOnly, VarList, EndLoc);
+ return new (Mem)
+ OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc, Mods, VarList, EndLoc);
}
OpenACCCopyOutClause *
OpenACCCopyOutClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
SourceLocation BeginLoc, SourceLocation LParenLoc,
- bool IsZero, ArrayRef<Expr *> VarList,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
SourceLocation EndLoc) {
void *Mem = C.Allocate(
OpenACCCopyOutClause::totalSizeToAlloc<Expr *>(VarList.size()));
- return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, IsZero,
+ return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, Mods,
VarList, EndLoc);
}
OpenACCCreateClause *
OpenACCCreateClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
SourceLocation BeginLoc, SourceLocation LParenLoc,
- bool IsZero, ArrayRef<Expr *> VarList,
+ OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
SourceLocation EndLoc) {
void *Mem =
C.Allocate(OpenACCCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
- return new (Mem) OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, IsZero,
- VarList, EndLoc);
+ return new (Mem)
+ OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, Mods, VarList, EndLoc);
}
OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create(
@@ -808,6 +809,8 @@ void OpenACCClausePrinter::VisitDeviceClause(const OpenACCDeviceClause &C) {
void OpenACCClausePrinter::VisitCopyClause(const OpenACCCopyClause &C) {
OS << C.getClauseKind() << '(';
+ if (C.getModifierList() != OpenACCModifierKind::Invalid)
+ OS << C.getModifierList() << ": ";
llvm::interleaveComma(C.getVarList(), OS,
[&](const Expr *E) { printExpr(E); });
OS << ")";
@@ -830,8 +833,8 @@ void OpenACCClausePrinter::VisitDeviceResidentClause(
void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) {
OS << C.getClauseKind() << '(';
- if (C.isReadOnly())
- OS << "readonly: ";
+ if (C.getModifierList() != OpenACCModifierKind::Invalid)
+ OS << C.getModifierList() << ": ";
llvm::interleaveComma(C.getVarList(), OS,
[&](const Expr *E) { printExpr(E); });
OS << ")";
@@ -839,8 +842,8 @@ void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) {
void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
OS << C.getClauseKind() << '(';
- if (C.isZero())
- OS << "zero: ";
+ if (C.getModifierList() != OpenACCModifierKind::Invalid)
+ OS << C.getModifierList() << ": ";
llvm::interleaveComma(C.getVarList(), OS,
[&](const Expr *E) { printExpr(E); });
OS << ")";
@@ -848,8 +851,8 @@ void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) {
OS << C.getClauseKind() << '(';
- if (C.isZero())
- OS << "zero: ";
+ if (C.getModifierList() != OpenACCModifierKind::Invalid)
+ OS << C.getModifierList() << ": ";
llvm::interleaveComma(C.getVarList(), OS,
[&](const Expr *E) { printExpr(E); });
OS << ")";
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 05f1953aa473c..be8d609974d81 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -405,9 +405,6 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
case OpenACCClauseKind::Async:
case OpenACCClauseKind::Auto:
case OpenACCClauseKind::Attach:
- case OpenACCClauseKind::Copy:
- case OpenACCClauseKind::PCopy:
- case OpenACCClauseKind::PresentOrCopy:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::If:
case OpenACCClauseKind::IfPresent:
@@ -457,26 +454,38 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
OS << ": force";
break;
+ case OpenACCClauseKind::Copy:
+ case OpenACCClauseKind::PCopy:
+ case OpenACCClauseKind::PresentOrCopy:
+ OS << " clause";
+ if (cast<OpenACCCopyClause>(C)->getModifierList() !=
+ OpenACCModifierKind::Invalid)
+ OS << " modifiers: " << cast<OpenACCCopyClause>(C)->getModifierList();
+ break;
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::PCopyIn:
case OpenACCClauseKind::PresentOrCopyIn:
OS << " clause";
- if (cast<OpenACCCopyInClause>(C)->isReadOnly())
- OS << " : readonly";
+ if (cast<OpenACCCopyInClause>(C)->getModifierList() !=
+ OpenACCModifierKind::Invalid)
+ OS << " modifiers: " << cast<OpenACCCopyInClause>(C)->getModifierList();
break;
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::PCopyOut:
case OpenACCClauseKind::PresentOrCopyOut:
OS << " clause";
- if (cast<OpenACCCopyOutClause>(C)->isZero())
- OS << " : zero";
+ if (cast<OpenACCCopyOutClause>(C)->getModifierList() !=
+ OpenACCModifierKind::Invalid)
+ OS << " modifiers: "
+ << cast<OpenACCCopyOutClause>(C)->getModifierList();
break;
case OpenACCClauseKind::Create:
case OpenACCClauseKind::PCreate:
case OpenACCClauseKind::PresentOrCreate:
OS << " clause";
- if (cast<OpenACCCreateClause>(C)->isZero())
- OS << " : zero";
+ if (cast<OpenACCCreateClause>(C)->getModifierList() !=
+ OpenACCModifierKind::Invalid)
+ OS << " modifiers: " << cast<OpenACCCreateClause>(C)->getModifierList();
break;
case OpenACCClauseKind::Wait:
OS << " clause";
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 4f4ae362983d0..64916995907c5 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -662,6 +662,70 @@ ExprResult Parser::ParseOpenACCConditionExpr() {
return R.isInvalid() ? ExprError() : R.get().second;
}
+// Tries to parse the 'modifier-list' for a 'copy', 'copyin', 'copyout', or
+// 'create' clause.
+OpenACCModifierKind Parser::tryParseModifierList(OpenACCClauseKind CK) {
+ // Use the tentative parsing to decide whether we are a comma-delmited list of
+ // identifers ending in a colon so we can do an actual parse with diagnostics.
+ {
+ RevertingTentativeParsingAction TPA{*this};
+ // capture any <ident><comma> pairs.
+ while (isTokenIdentifierOrKeyword(*this, getCurToken()) &&
+ NextToken().is(tok::comma)) {
+ ConsumeToken();
+ ConsumeToken();
+ }
+
+ if (!isTokenIdentifierOrKeyword(*this, getCurToken()) ||
+ !NextToken().is(tok::colon)) {
+ // No modifiers as this isn't a valid modifier-list.
+ return OpenACCModifierKind::Invalid;
+ }
+ }
+
+ auto GetModKind = [](Token T) {
+ return StringSwitch<OpenACCModifierKind>(T.getIdentifierInfo()->getName())
+ .Case("always", OpenACCModifierKind::Always)
+ .Case("alwaysin", OpenACCModifierKind::AlwaysIn)
+ .Case("alwaysout", OpenACCModifierKind::AlwaysOut)
+ .Case("readonly", OpenACCModifierKind::Readonly)
+ .Case("zero", OpenACCModifierKind::Zero)
+ .Default(OpenACCModifierKind::Invalid);
+ };
+
+ OpenACCModifierKind CurModList = OpenACCModifierKind::Invalid;
+ auto ConsumeModKind = [&]() {
+ Token IdentToken = getCurToken();
+ OpenACCModifierKind NewKind = GetModKind(IdentToken);
+
+ if (NewKind == OpenACCModifierKind::Invalid)
+ Diag(IdentToken.getLocation(), diag::err_acc_modifier)
+ << diag::ACCModifier::Unknown << IdentToken.getIdentifierInfo() << CK;
+ else if ((NewKind & CurModList) != OpenACCModifierKind::Invalid)
+ Diag(IdentToken.getLocation(), diag::err_acc_modifier)
+ << diag::ACCModifier::Duplicate << IdentToken.getIdentifierInfo()
+ << CK;
+ else
+ CurModList |= NewKind;
+
+ // Consumes the identifier.
+ ConsumeToken();
+ // Consumes the comma or colon.
+ ConsumeToken();
+ };
+
+ // Inspect all but the last item. We inspected enough to know that our current
+ // token is the identifier-like thing, so just check for the comma.
+ while (NextToken().is(tok::comma))
+ ConsumeModKind();
+
+ // Above we confirmed that this should be correct/we should be on the last
+ // item.
+ ConsumeModKind();
+
+ return CurModList;
+}
+
// 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
@@ -981,26 +1045,21 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
break;
}
+ case OpenACCClauseKind::Copy:
+ case OpenACCClauseKind::PCopy:
+ case OpenACCClauseKind::PresentOrCopy:
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::PCopyIn:
- case OpenACCClauseKind::PresentOrCopyIn: {
- bool IsReadOnly = tryParseAndConsumeSpecialTokenKind(
- *this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind);
- ParsedClause.setVarListDetails(ParseOpenACCVarList(DirKind, ClauseKind),
- IsReadOnly,
- /*IsZero=*/false);
- break;
- }
- case OpenACCClauseKind::Create:
- case OpenACCClauseKind::PCreate:
- case OpenACCClauseKind::PresentOrCreate:
+ case OpenACCClauseKind::PresentOrCopyIn:
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::PCopyOut:
- case OpenACCClauseKind::PresentOrCopyOut: {
- bool IsZero = tryParseAndConsumeSpecialTokenKind(
- *this, OpenACCSpecialTokenKind::Zero, ClauseKind);
+ case OpenACCClauseKind::PresentOrCopyOut:
+ case OpenACCClauseKind::Create:
+ case OpenACCClauseKind::PCreate:
+ case OpenACCClauseKind::PresentOrCreate: {
+ OpenACCModifierKind ModList = tryParseModifierList(ClauseKind);
ParsedClause.setVarListDetails(ParseOpenACCVarList(DirKind, ClauseKind),
- /*IsReadOnly=*/false, IsZero);
+ ModList);
break;
}
case OpenACCClauseKind::Reduction: {
@@ -1026,15 +1085,12 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
case OpenACCClauseKind::Detach:
case OpenACCClauseKind::DevicePtr:
case OpenACCClauseKind::UseDevice:
- case OpenACCClauseKind::Copy:
- case OpenACCClauseKind::PCopy:
- case OpenACCClauseKind::PresentOrCopy:
case OpenACCClauseKind::FirstPrivate:
case OpenACCClauseKind::NoCreate:
case OpenACCClauseKind::Present:
case OpenACCClauseKind::Private:
ParsedClause.setVarListDetails(ParseOpenACCVarList(DirKind, ClauseKind),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
break;
case OpenACCClauseKind::Collapse: {
bool HasForce = tryParseAndConsumeSpecialTokenKind(
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 819fb0853e8f5..c80f5f848f60b 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2070,7 +2070,6 @@ void SemaOpenACC::CheckRoutineDecl(SourceLocation DirLoc,
return;
}
- // TODO ERICH: Check bind here.
auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
for (auto *A : NextParsedFDecl->attrs()) {
// OpenACC 3.3 2.15:
diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp
index a98b6712014cd..7d10c50d404d2 100644
--- a/clang/lib/Sema/SemaOpenACCClause.cpp
+++ b/clang/lib/Sema/SemaOpenACCClause.cpp
@@ -683,6 +683,59 @@ class SemaOpenACCClauseVisitor {
return false;
}
+ OpenACCModifierKind
+ CheckModifierList(SemaOpenACC::OpenACCParsedClause &Clause,
+ OpenACCModifierKind Mods) {
+ auto CheckSingle = [=](OpenACCModifierKind CurMods,
+ OpenACCModifierKind ValidKinds,
+ OpenACCModifierKind Bit) {
+ if (!isOpenACCModifierBitSet(CurMods, Bit) ||
+ isOpenACCModifierBitSet(ValidKinds, Bit))
+ return CurMods;
+
+ SemaRef.Diag(Clause.getLParenLoc(), diag::err_acc_invalid_modifier)
+ << Bit << Clause.getClauseKind();
+
+ return CurMods ^ Bit;
+ };
+ auto Check = [&](OpenACCModifierKind ValidKinds) {
+ if ((Mods | ValidKinds) == ValidKinds)
+ return Mods;
+
+ Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Always);
+ Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysIn);
+ Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysOut);
+ Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Readonly);
+ Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Zero);
+ return Mods;
+ };
+
+ switch (Clause.getClauseKind()) {
+ default:
+ llvm_unreachable("Only for copy, copyin, copyout, create");
+ case OpenACCClauseKind::Copy:
+ case OpenACCClauseKind::PCopy:
+ case OpenACCClauseKind::PresentOrCopy:
+ return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
+ OpenACCModifierKind::AlwaysOut);
+ case OpenACCClauseKind::CopyIn:
+ case OpenACCClauseKind::PCopyIn:
+ case OpenACCClauseKind::PresentOrCopyIn:
+ return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
+ OpenACCModifierKind::Readonly);
+ case OpenACCClauseKind::CopyOut:
+ case OpenACCClauseKind::PCopyOut:
+ case OpenACCClauseKind::PresentOrCopyOut:
+ return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
+ OpenACCModifierKind::Zero);
+ case OpenACCClauseKind::Create:
+ case OpenACCClauseKind::PCreate:
+ case OpenACCClauseKind::PresentOrCreate:
+ return Check(OpenACCModifierKind::Zero);
+ }
+ llvm_unreachable("didn't return from switch above?");
+ }
+
public:
SemaOpenACCClauseVisitor(SemaOpenACC &S,
ArrayRef<const OpenACCClause *> ExistingClauses)
@@ -1070,7 +1123,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))
return nullptr;
return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
@@ -1106,25 +1159,28 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
// really isn't anything to do here. GCC does some duplicate-finding, though
// it isn't apparent in the standard where this is justified.
+ OpenACCModifierKind NewMods =
+ CheckModifierList(Clause, Clause.getModifierList());
+
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, NewMods))
return nullptr;
return OpenACCCopyClause::Create(
Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
- Clause.getVarList(), Clause.getEndLoc());
+ Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc());
}
OpenACCClause *SemaOpenACCClauseVisitor::VisitLinkClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))
return nullptr;
Clause.setVarListDetails(SemaRef.CheckLinkClauseVarList(Clause.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
return OpenACCLinkClause::Create(Ctx, Clause.getBeginLoc(),
Clause.getLParenLoc(), Clause.getVarList(),
@@ -1135,7 +1191,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceResidentClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))
return nullptr;
return OpenACCDeviceResidentClause::Create(
@@ -1149,14 +1205,17 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
// really isn't anything to do here. GCC does some duplicate-finding, though
// it isn't apparent in the standard where this is justified.
+ OpenACCModifierKind NewMods =
+ CheckModifierList(Clause, Clause.getModifierList());
+
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, NewMods))
return nullptr;
return OpenACCCopyInClause::Create(
Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
- Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
+ Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc());
}
OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
@@ -1165,14 +1224,17 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
// really isn't anything to do here. GCC does some duplicate-finding, though
// it isn't apparent in the standard where this is justified.
+ OpenACCModifierKind NewMods =
+ CheckModifierList(Clause, Clause.getModifierList());
+
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, NewMods))
return nullptr;
return OpenACCCopyOutClause::Create(
Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
- Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
+ Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc());
}
OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
@@ -1181,14 +1243,17 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
// really isn't anything to do here. GCC does some duplicate-finding, though
// it isn't apparent in the standard where this is justified.
+ OpenACCModifierKind NewMods =
+ CheckModifierList(Clause, Clause.getModifierList());
+
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, NewMods))
return nullptr;
return OpenACCCreateClause::Create(
Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
- Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
+ Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc());
}
OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
@@ -1199,8 +1264,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
llvm::erase_if(VarList, [&](Expr *E) {
return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
});
- Clause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
Clause.getLParenLoc(), Clause.getVarList(),
Clause.getEndLoc());
@@ -1214,8 +1278,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
llvm::erase_if(VarList, [&](Expr *E) {
return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
});
- Clause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
Clause.getLParenLoc(), Clause.getVarList(),
Clause.getEndLoc());
@@ -1248,12 +1311,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
llvm::erase_if(VarList, [&](Expr *E) {
return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
});
- Clause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
// 'declare' has some restrictions that need to be enforced separately, so
// check it here.
- if (SemaRef.CheckDeclareClause(Clause))
+ if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))
return nullptr;
return OpenACCDevicePtrClause::Create(
@@ -2396,7 +2458,8 @@ SemaOpenACC::CheckLinkClauseVarList(ArrayRef<Expr *> VarExprs) {
return NewVarList;
}
-bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause) {
+bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
+ OpenACCModifierKind Mods) {
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Declare)
return false;
@@ -2487,7 +2550,6 @@ bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause) {
FilteredVarList.push_back(VarExpr);
}
- Clause.setVarListDetails(FilteredVarList, Clause.isReadOnly(),
- Clause.isZero());
+ Clause.setVarListDetails(FilteredVarList, Mods);
return false;
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2d6f2ca67af8a..e0f7ccc4674d8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1186,22 +1186,24 @@ void OpenACCDeclClauseInstantiator::VisitVectorClause(
void OpenACCDeclClauseInstantiator::VisitCopyClause(
const OpenACCCopyClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ C.getModifierList());
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause, C.getModifierList()))
return;
NewClause = OpenACCCopyClause::Create(
SemaRef.getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.getVarList(), ParsedClause.getEndLoc());
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
+ ParsedClause.getEndLoc());
}
void OpenACCDeclClauseInstantiator::VisitLinkClause(
const OpenACCLinkClause &C) {
ParsedClause.setVarListDetails(
SemaRef.OpenACC().CheckLinkClauseVarList(VisitVarList(C.getVarList())),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause,
+ OpenACCModifierKind::Invalid))
return;
NewClause = OpenACCLinkClause::Create(
@@ -1213,8 +1215,9 @@ void OpenACCDeclClauseInstantiator::VisitLinkClause(
void OpenACCDeclClauseInstantiator::VisitDeviceResidentClause(
const OpenACCDeviceResidentClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ OpenACCModifierKind::Invalid);
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause,
+ OpenACCModifierKind::Invalid))
return;
NewClause = OpenACCDeviceResidentClause::Create(
SemaRef.getASTContext(), ParsedClause.getBeginLoc(),
@@ -1224,48 +1227,49 @@ void OpenACCDeclClauseInstantiator::VisitDeviceResidentClause(
void OpenACCDeclClauseInstantiator::VisitCopyInClause(
const OpenACCCopyInClause &C) {
- ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
- /*IsZero=*/false);
+ ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
+ C.getModifierList());
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause, C.getModifierList()))
return;
NewClause = OpenACCCopyInClause::Create(
SemaRef.getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isReadOnly(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
void OpenACCDeclClauseInstantiator::VisitCopyOutClause(
const OpenACCCopyOutClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, C.isZero());
+ C.getModifierList());
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause, C.getModifierList()))
return;
NewClause = OpenACCCopyOutClause::Create(
SemaRef.getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isZero(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
void OpenACCDeclClauseInstantiator::VisitCreateClause(
const OpenACCCreateClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, C.isZero());
+ C.getModifierList());
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause, C.getModifierList()))
return;
NewClause = OpenACCCreateClause::Create(
SemaRef.getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isZero(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
void OpenACCDeclClauseInstantiator::VisitPresentClause(
const OpenACCPresentClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ OpenACCModifierKind::Invalid);
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause,
+ OpenACCModifierKind::Invalid))
return;
NewClause = OpenACCPresentClause::Create(
SemaRef.getASTContext(), ParsedClause.getBeginLoc(),
@@ -1282,9 +1286,9 @@ void OpenACCDeclClauseInstantiator::VisitDevicePtrClause(
OpenACCClauseKind::DevicePtr, E);
}),
VarList.end());
- ParsedClause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
- if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause))
+ ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
+ if (SemaRef.OpenACC().CheckDeclareClause(ParsedClause,
+ OpenACCModifierKind::Invalid))
return;
NewClause = OpenACCDevicePtrClause::Create(
SemaRef.getASTContext(), ParsedClause.getBeginLoc(),
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 237c5a9ef501b..b9bf748a2e98e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11760,7 +11760,7 @@ void OpenACCClauseTransform<Derived>::VisitSelfClause(
}
ParsedClause.setVarListDetails(InstantiatedVarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCSelfClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11818,7 +11818,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitPrivateClause(
const OpenACCPrivateClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCPrivateClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11830,7 +11830,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitHostClause(
const OpenACCHostClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCHostClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11842,7 +11842,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitDeviceClause(
const OpenACCDeviceClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCDeviceClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11854,7 +11854,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
const OpenACCFirstPrivateClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCFirstPrivateClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11866,7 +11866,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
const OpenACCNoCreateClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCNoCreateClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11878,7 +11878,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitPresentClause(
const OpenACCPresentClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCPresentClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
@@ -11890,12 +11890,13 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitCopyClause(
const OpenACCCopyClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ C.getModifierList());
NewClause = OpenACCCopyClause::Create(
Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.getVarList(), ParsedClause.getEndLoc());
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
+ ParsedClause.getEndLoc());
}
template <typename Derived>
@@ -11923,13 +11924,13 @@ void OpenACCClauseTransform<Derived>::VisitBindClause(
template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitCopyInClause(
const OpenACCCopyInClause &C) {
- ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
- /*IsZero=*/false);
+ ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
+ C.getModifierList());
NewClause = OpenACCCopyInClause::Create(
Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isReadOnly(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
@@ -11937,12 +11938,12 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
const OpenACCCopyOutClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, C.isZero());
+ C.getModifierList());
NewClause = OpenACCCopyOutClause::Create(
Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isZero(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
@@ -11950,12 +11951,12 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitCreateClause(
const OpenACCCreateClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, C.isZero());
+ C.getModifierList());
NewClause = OpenACCCreateClause::Create(
Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
- ParsedClause.isZero(), ParsedClause.getVarList(),
+ ParsedClause.getModifierList(), ParsedClause.getVarList(),
ParsedClause.getEndLoc());
}
template <typename Derived>
@@ -11969,8 +11970,7 @@ void OpenACCClauseTransform<Derived>::VisitAttachClause(
OpenACCClauseKind::Attach, E);
});
- ParsedClause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
NewClause = OpenACCAttachClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
@@ -11991,8 +11991,7 @@ void OpenACCClauseTransform<Derived>::VisitDetachClause(
}),
VarList.end());
- ParsedClause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
NewClause = OpenACCDetachClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
@@ -12003,7 +12002,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitDeleteClause(
const OpenACCDeleteClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCDeleteClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
@@ -12014,7 +12013,7 @@ template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
const OpenACCUseDeviceClause &C) {
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ OpenACCModifierKind::Invalid);
NewClause = OpenACCUseDeviceClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
@@ -12032,8 +12031,7 @@ void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
OpenACCClauseKind::DevicePtr, E);
});
- ParsedClause.setVarListDetails(VarList,
- /*IsReadOnly=*/false, /*IsZero=*/false);
+ ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
NewClause = OpenACCDevicePtrClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 38697eb835134..d8d77e7f55232 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -12715,36 +12715,37 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
case OpenACCClauseKind::PresentOrCopy:
case OpenACCClauseKind::Copy: {
SourceLocation LParenLoc = readSourceLocation();
+ OpenACCModifierKind ModList = readEnum<OpenACCModifierKind>();
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
return OpenACCCopyClause::Create(getContext(), ClauseKind, BeginLoc,
- LParenLoc, VarList, EndLoc);
+ LParenLoc, ModList, VarList, EndLoc);
}
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::PCopyIn:
case OpenACCClauseKind::PresentOrCopyIn: {
SourceLocation LParenLoc = readSourceLocation();
- bool IsReadOnly = readBool();
+ OpenACCModifierKind ModList = readEnum<OpenACCModifierKind>();
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
return OpenACCCopyInClause::Create(getContext(), ClauseKind, BeginLoc,
- LParenLoc, IsReadOnly, VarList, EndLoc);
+ LParenLoc, ModList, VarList, EndLoc);
}
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::PCopyOut:
case OpenACCClauseKind::PresentOrCopyOut: {
SourceLocation LParenLoc = readSourceLocation();
- bool IsZero = readBool();
+ OpenACCModifierKind ModList = readEnum<OpenACCModifierKind>();
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
return OpenACCCopyOutClause::Create(getContext(), ClauseKind, BeginLoc,
- LParenLoc, IsZero, VarList, EndLoc);
+ LParenLoc, ModList, VarList, EndLoc);
}
case OpenACCClauseKind::Create:
case OpenACCClauseKind::PCreate:
case OpenACCClauseKind::PresentOrCreate: {
SourceLocation LParenLoc = readSourceLocation();
- bool IsZero = readBool();
+ OpenACCModifierKind ModList = readEnum<OpenACCModifierKind>();
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
return OpenACCCreateClause::Create(getContext(), ClauseKind, BeginLoc,
- LParenLoc, IsZero, VarList, EndLoc);
+ LParenLoc, ModList, VarList, EndLoc);
}
case OpenACCClauseKind::Async: {
SourceLocation LParenLoc = readSourceLocation();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index f27be5fb4c76c..a48c05061626a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8715,6 +8715,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::PresentOrCopy: {
const auto *CC = cast<OpenACCCopyClause>(C);
writeSourceLocation(CC->getLParenLoc());
+ writeEnum(CC->getModifierList());
writeOpenACCVarList(CC);
return;
}
@@ -8723,7 +8724,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::PresentOrCopyIn: {
const auto *CIC = cast<OpenACCCopyInClause>(C);
writeSourceLocation(CIC->getLParenLoc());
- writeBool(CIC->isReadOnly());
+ writeEnum(CIC->getModifierList());
writeOpenACCVarList(CIC);
return;
}
@@ -8732,7 +8733,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::PresentOrCopyOut: {
const auto *COC = cast<OpenACCCopyOutClause>(C);
writeSourceLocation(COC->getLParenLoc());
- writeBool(COC->isZero());
+ writeEnum(COC->getModifierList());
writeOpenACCVarList(COC);
return;
}
@@ -8741,7 +8742,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::PresentOrCreate: {
const auto *CC = cast<OpenACCCreateClause>(C);
writeSourceLocation(CC->getLParenLoc());
- writeBool(CC->isZero());
+ writeEnum(CC->getModifierList());
writeOpenACCVarList(CC);
return;
}
diff --git a/clang/test/AST/ast-print-openacc-combined-construct.cpp b/clang/test/AST/ast-print-openacc-combined-construct.cpp
index b5afc1515aa18..be959fb2b6117 100644
--- a/clang/test/AST/ast-print-openacc-combined-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-combined-construct.cpp
@@ -171,16 +171,16 @@ void foo() {
#pragma acc parallel loop no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);
-// CHECK: #pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
-#pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
+// CHECK: #pragma acc parallel loop copy(alwaysin: i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
+#pragma acc parallel loop copy(alwaysin: i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);
-// CHECK: #pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
-#pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
+// CHECK: #pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(always, alwaysin: i, array[1], array, array[1:2])
+#pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(always, alwaysin: i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);
-// CHECK: #pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
-#pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
+// CHECK: #pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(always, alwaysin: i, array[1], array, array[1:2])
+#pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(always, alwaysin: i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);
// CHECK: #pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
diff --git a/clang/test/AST/ast-print-openacc-compute-construct.cpp b/clang/test/AST/ast-print-openacc-compute-construct.cpp
index 9516bfd843000..1fbb81a220aab 100644
--- a/clang/test/AST/ast-print-openacc-compute-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-compute-construct.cpp
@@ -56,12 +56,16 @@ void foo() {
#pragma acc parallel no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
while(true);
-// CHECK: #pragma acc parallel copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
-#pragma acc parallel copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
+// CHECK: #pragma acc parallel copy(i, array[1], array, array[1:2]) pcopy(alwaysin: i, array[1], array, array[1:2]) present_or_copy(always, alwaysout: i, array[1], array, array[1:2])
+#pragma acc parallel copy(i, array[1], array, array[1:2]) pcopy(alwaysin:i, array[1], array, array[1:2]) present_or_copy(always, alwaysout: i, array[1], array, array[1:2])
while(true);
-// CHECK: #pragma acc parallel copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
-#pragma acc parallel copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
+// CHECK: #pragma acc parallel copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(always, readonly: i, array[1], array, array[1:2])
+#pragma acc parallel copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(readonly, always: i, array[1], array, array[1:2])
+ while(true);
+
+// CHECK: #pragma acc parallel copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(always, zero: i, array[1], array, array[1:2])
+#pragma acc parallel copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(always, zero: i, array[1], array, array[1:2])
while(true);
// CHECK: #pragma acc parallel create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
diff --git a/clang/test/AST/ast-print-openacc-data-construct.cpp b/clang/test/AST/ast-print-openacc-data-construct.cpp
index 6d6f54cb45ada..b7d2428fb605a 100644
--- a/clang/test/AST/ast-print-openacc-data-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-data-construct.cpp
@@ -17,8 +17,8 @@ void foo() {
// CHECK: #pragma acc enter data copyin(Var)
#pragma acc enter data copyin(Var)
;
-// CHECK: #pragma acc exit data copyout(Var)
-#pragma acc exit data copyout(Var)
+// CHECK: #pragma acc exit data copyout(always, zero: Var)
+#pragma acc exit data copyout(zero, always: Var)
;
// CHECK: #pragma acc host_data use_device(Var)
#pragma acc host_data use_device(Var)
@@ -44,8 +44,8 @@ void foo() {
// CHECK: #pragma acc data default(none) async(i)
#pragma acc data default(none) async(i)
;
-// CHECK: #pragma acc enter data copyin(i) async(i)
-#pragma acc enter data copyin(i) async(i)
+// CHECK: #pragma acc enter data copyin(always: i) async(i)
+#pragma acc enter data copyin(always: i) async(i)
// CHECK: #pragma acc exit data copyout(i) async
#pragma acc exit data copyout(i) async
@@ -56,8 +56,8 @@ void foo() {
// CHECK: #pragma acc enter data copyin(Var) wait
#pragma acc enter data copyin(Var) wait
-// CHECK: #pragma acc exit data copyout(Var) wait(*iPtr, i)
-#pragma acc exit data copyout(Var) wait(*iPtr, i)
+// CHECK: #pragma acc exit data copyout(always, zero: Var) wait(*iPtr, i)
+#pragma acc exit data copyout(always, zero: Var) wait(*iPtr, i)
// CHECK: #pragma acc data default(none) wait(queues: *iPtr, i)
#pragma acc data default(none) wait(queues:*iPtr, i)
@@ -88,8 +88,8 @@ void foo() {
#pragma acc data present(i, array[1], array, array[1:2])
;
-// CHECK: #pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
-#pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
+// CHECK: #pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(alwaysin, alwaysout: i, array[1], array, array[1:2])
+#pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(alwaysin, alwaysout: i, array[1], array, array[1:2])
;
// CHECK: #pragma acc enter data copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
diff --git a/clang/test/AST/ast-print-openacc-declare-construct.cpp b/clang/test/AST/ast-print-openacc-declare-construct.cpp
index fce4afc6aedae..2a61b08c5500b 100644
--- a/clang/test/AST/ast-print-openacc-declare-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-declare-construct.cpp
@@ -5,8 +5,8 @@ int GlobalArray[5];
int GlobalArray2[5];
// CHECK: #pragma acc declare deviceptr(Global) copyin(GlobalArray)
#pragma acc declare deviceptr(Global), copyin(GlobalArray)
-// CHECK: #pragma acc declare create(Global2, GlobalArray2)
-#pragma acc declare create(Global2, GlobalArray2)
+// CHECK: #pragma acc declare create(zero: Global2, GlobalArray2)
+#pragma acc declare create(zero: Global2, GlobalArray2)
namespace NS {
int NSVar;
@@ -18,8 +18,8 @@ int NSArray[5];
struct Struct {
static const int StaticMem = 5;
static const int StaticMemArray[5];
-// CHECK: #pragma acc declare copyin(StaticMem, StaticMemArray)
-#pragma acc declare copyin(StaticMem, StaticMemArray)
+// CHECK: #pragma acc declare copyin(always, alwaysin: StaticMem, StaticMemArray)
+#pragma acc declare copyin(always, alwaysin: StaticMem, StaticMemArray)
void MemFunc1(int Arg) {
int Local;
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index e31b7492dab2c..2319b1abb9e83 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -verify -fopenacc -std=c99
-// RUNX: %clang_cc1 %s -verify -fopenacc
-// RUNX: %clang_cc1 %s -verify -fopenacc -x c++
+// RUN: %clang_cc1 %s -verify=expected,c -fopenacc -std=c99
+// RUN: %clang_cc1 %s -verify=expected,c -fopenacc
+// RUN: %clang_cc1 %s -verify=expected,cpp -fopenacc -x c++
void func() {
@@ -422,7 +422,8 @@ void VarListClauses() {
#pragma acc serial copy(HasMem.MemArr[:]), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{expected expression}}
+ // cpp-error at +2{{expected unqualified-id}}
+ // c-error at +1{{expected expression}}
#pragma acc serial copy(HasMem.MemArr[::]), self
for(int i = 0; i < 5;++i) {}
@@ -443,6 +444,21 @@ void VarListClauses() {
#pragma acc serial present_or_copy(HasMem.MemArr[3:])
for(int i = 0; i < 5;++i) {}
+ // expected-error at +2{{unknown modifier 'foo' in OpenACC modifier-list on 'copy' clause}}
+ // expected-error at +1{{unknown modifier 'bar' in OpenACC modifier-list on 'copy' clause}}
+#pragma acc parallel copy(foo, bar: HasMem.MemArr[3:]) self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +1{{duplicate modifier 'always' in OpenACC modifier-list on 'copy' clause}}
+#pragma acc parallel copy(always, alwaysin, always: HasMem.MemArr[3:]) self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +3{{use of undeclared identifier 'always'}}
+ // expected-error at +2{{use of undeclared identifier 'alwaysin'}}
+ // expected-error at +1{{use of undeclared identifier 'always'}}
+#pragma acc parallel copy(always, alwaysin, always, HasMem.MemArr[3:]) self
+ for(int i = 0; i < 5;++i) {}
+
// expected-error at +2 2{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
// expected-error at +1{{expected ','}}
#pragma acc host_data use_device(s.array[s.value] s.array[s.value :5] ), if_present
@@ -580,15 +596,15 @@ void VarListClauses() {
#pragma acc serial copyout(zero s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'readonly' on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
#pragma acc serial copyout(readonly:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'copyout' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'copyout' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
@@ -597,6 +613,15 @@ void VarListClauses() {
#pragma acc serial copyout(invalid s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
+ // expected-error at +1{{unknown modifier 'bar' in OpenACC modifier-list on 'copyout' clause}}
+#pragma acc serial copyout(invalid, bar: s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +1{{duplicate modifier 'zero' in OpenACC modifier-list on 'copyout' clause}}
+#pragma acc serial copyout(zero, zero, always: s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
// expected-error at +1{{expected ','}}
#pragma acc serial create(s.array[s.value] s.array[s.value :5] ), self
for(int i = 0; i < 5;++i) {}
@@ -607,6 +632,20 @@ void VarListClauses() {
#pragma acc serial create(zero:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc serial create(always, zero:s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +2{{duplicate modifier 'always' in OpenACC modifier-list on 'create' clause}}
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc serial create(always, always, zero:s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc serial create(always, invalid, zero:s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
// expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
#pragma acc serial pcreate(s.array[s.value : 5], s.value)
for(int i = 0; i < 5;++i) {}
@@ -623,15 +662,15 @@ void VarListClauses() {
#pragma acc serial create(zero s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'readonly' on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
#pragma acc serial create(readonly:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'create' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
#pragma acc serial create(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'create' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
#pragma acc serial create(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
@@ -666,15 +705,15 @@ void VarListClauses() {
#pragma acc serial copyin(readonly s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'zero' on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
#pragma acc serial copyin(zero :s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'copyin' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyin' clause}}
#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +1{{invalid tag 'invalid' on 'copyin' clause}}
+ // expected-error at +1{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyin' clause}}
#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
@@ -682,6 +721,15 @@ void VarListClauses() {
// expected-error at +1{{expected ','}}
#pragma acc serial copyin(invalid s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +2{{unknown modifier 'foo' in OpenACC modifier-list on 'copyin' clause}}
+ // expected-error at +1{{unknown modifier 'bar' in OpenACC modifier-list on 'copyin' clause}}
+#pragma acc serial copyin(foo, bar: s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
+
+ // expected-error at +1{{duplicate modifier 'readonly' in OpenACC modifier-list on 'copyin' clause}}
+#pragma acc serial copyin(always, readonly, readonly: s.array[s.value : 5], s.value), self
+ for(int i = 0; i < 5;++i) {}
}
void ReductionClauseParsing() {
diff --git a/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
index a696badb0847c..75e5d0283889e 100644
--- a/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
@@ -14,18 +14,18 @@ void NormalUses(float *PointerParam) {
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global)
+#pragma acc parallel loop copy(always:GlobalArray) pcopy(alwaysin:PointerParam[Global]) present_or_copy(alwaysout: Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause modifiers: always
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: alwaysin
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysout
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: ForStmt
// CHECK:NullStmt
@@ -42,12 +42,12 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
+#pragma acc parallel loop copy(t) pcopy(always, alwaysin, alwaysout: NTTP, u) present_or_copy(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always, alwaysin, alwaysout
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copy clause
@@ -75,7 +75,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always, alwaysin, alwaysout
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/combined-construct-copy-clause.c b/clang/test/SemaOpenACC/combined-construct-copy-clause.c
index c588fd8d94987..07c412c621ff1 100644
--- a/clang/test/SemaOpenACC/combined-construct-copy-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-copy-clause.c
@@ -70,3 +70,18 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copy(LocalInt)
for(int i = 5; i < 10;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc parallel loop copy(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+#pragma acc serial loop copy(readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc kernels loop copy(zero: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc parallel loop copy(always, alwaysin, alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
index e7ac8238a7db6..f7b5cb841b966 100644
--- a/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
@@ -14,18 +14,18 @@ void NormalUses(float *PointerParam) {
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global)
+#pragma acc parallel loop copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(always, alwaysin: Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
@@ -42,12 +42,12 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
+#pragma acc parallel loop copyin(always, readonly, alwaysin: t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
- // CHECK-NEXT: copyin clause
+ // CHECK-NEXT: copyin clause modifiers: always, alwaysin, readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyin clause
@@ -73,9 +73,9 @@ void TemplUses(T t, U u) {
// #pragma acc parallel copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
- // CHECK-NEXT: copyin clause
+ // CHECK-NEXT: copyin clause modifiers: always, alwaysin, readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/combined-construct-copyin-clause.c b/clang/test/SemaOpenACC/combined-construct-copyin-clause.c
index 4cb635ddb2470..b4a6eafdb9ebd 100644
--- a/clang/test/SemaOpenACC/combined-construct-copyin-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-copyin-clause.c
@@ -61,7 +61,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
- // expected-error at +2{{invalid tag 'invalid' on 'copyin' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyin' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
@@ -76,3 +76,19 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copyin(LocalInt)
for(int i = 5; i < 10;++i);
}
+
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc parallel loop copyin(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+#pragma acc serial loop copyin(alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc kernels loop copyin(zero: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc parallel loop copyin(always, alwaysin, readonly: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
index 02eda413dd53f..ec4451e9df7d3 100644
--- a/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
@@ -14,18 +14,18 @@ void NormalUses(float *PointerParam) {
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global)
+#pragma acc parallel loop copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(always, alwaysin: Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: For
// CHECK: NullStmt
@@ -42,12 +42,12 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc parallel loop copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
+#pragma acc parallel loop copyout(always, alwaysin: t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
- // CHECK-NEXT: copyout clause
+ // CHECK-NEXT: copyout clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyout clause
@@ -73,9 +73,9 @@ void TemplUses(T t, U u) {
// #pragma acc parallel copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
- // CHECK-NEXT: copyout clause
+ // CHECK-NEXT: copyout clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/combined-construct-copyout-clause.c b/clang/test/SemaOpenACC/combined-construct-copyout-clause.c
index c43f9592062fa..6621adb5c6124 100644
--- a/clang/test/SemaOpenACC/combined-construct-copyout-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-copyout-clause.c
@@ -61,7 +61,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
- // expected-error at +2{{invalid tag 'invalid' on 'copyout' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
@@ -76,3 +76,19 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copyout(LocalInt)
for(int i = 0; i < 6;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc parallel loop copyout(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 0; i < 6;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+#pragma acc serial loop copyout(alwaysout: V1)
+ for(int i = 0; i < 6;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc kernels loop copyout(readonly: V1)
+ for(int i = 0; i < 6;++i);
+#pragma acc parallel loop copyout(always, alwaysin, zero: V1)
+ for(int i = 0; i < 6;++i);
+}
+
diff --git a/clang/test/SemaOpenACC/combined-construct-create-ast.cpp b/clang/test/SemaOpenACC/combined-construct-create-ast.cpp
index 16268eda4e5d2..888654e690c0b 100644
--- a/clang/test/SemaOpenACC/combined-construct-create-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-create-ast.cpp
@@ -19,7 +19,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -47,7 +47,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_create clause
@@ -75,7 +75,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/combined-construct-create-clause.c b/clang/test/SemaOpenACC/combined-construct-create-clause.c
index c17e6921a7da2..bf7dfe83a0511 100644
--- a/clang/test/SemaOpenACC/combined-construct-create-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-create-clause.c
@@ -61,7 +61,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
- // expected-error at +2{{invalid tag 'invalid' on 'create' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
@@ -76,3 +76,27 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_create(LocalInt)
for(int i = 5; i < 10;++i);
}
+
+void ModList() {
+ int V1;
+ // expected-error at +4{{OpenACC 'always' modifier not valid on 'create' clause}}
+ // expected-error at +3{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc parallel loop create(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc serial loop create(always: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+#pragma acc kernels loop create(alwaysin: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+#pragma acc parallel loop create(alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc serial loop create(readonly: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc kernels loop create(zero: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-copy-clause.c b/clang/test/SemaOpenACC/compute-construct-copy-clause.c
index c4a9963ef4c7c..e83bdab64c246 100644
--- a/clang/test/SemaOpenACC/compute-construct-copy-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-copy-clause.c
@@ -70,3 +70,18 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copy(LocalInt)
for(int i = 5; i < 10;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc parallel copy(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+#pragma acc serial copy(readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc kernels copy(zero: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc parallel copy(always, alwaysin, alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c
index 84b5c29f3bf67..eaa8a604df32a 100644
--- a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c
@@ -61,7 +61,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel copyin((float)ArrayParam[2])
while(1);
- // expected-error at +2{{invalid tag 'invalid' on 'copyin' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyin' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel copyin(invalid:(float)ArrayParam[2])
while(1);
@@ -76,3 +76,18 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copyin(LocalInt)
for(int i = 5; i < 10;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc parallel copyin(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+#pragma acc serial copyin(alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc kernels copyin(zero: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc parallel copyin(always, alwaysin, readonly: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c
index da64be291494e..f1ea21d0824cc 100644
--- a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c
@@ -61,7 +61,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel copyout((float)ArrayParam[2])
while(1);
- // expected-error at +2{{invalid tag 'invalid' on 'copyout' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel copyout(invalid:(float)ArrayParam[2])
while(1);
@@ -76,3 +76,18 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_copyout(LocalInt)
for(int i = 0; i < 6;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc parallel copyout(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 0; i < 6;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+#pragma acc serial copyout(alwaysout: V1)
+ for(int i = 0; i < 6;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc kernels copyout(readonly: V1)
+ for(int i = 0; i < 6;++i);
+#pragma acc parallel copyout(always, alwaysin, zero: V1)
+ for(int i = 0; i < 6;++i);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-create-clause.c b/clang/test/SemaOpenACC/compute-construct-create-clause.c
index d54a82a4e7dfa..926c5b88a5115 100644
--- a/clang/test/SemaOpenACC/compute-construct-create-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-create-clause.c
@@ -62,7 +62,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel create((float)ArrayParam[2])
while(1);
- // expected-error at +2{{invalid tag 'invalid' on 'create' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel create(invalid:(float)ArrayParam[2])
while(1);
@@ -77,3 +77,26 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc loop present_or_create(LocalInt)
for(int i = 5; i < 10;++i);
}
+void ModList() {
+ int V1;
+ // expected-error at +4{{OpenACC 'always' modifier not valid on 'create' clause}}
+ // expected-error at +3{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc parallel create(always, alwaysin, alwaysout, zero, readonly: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc serial create(always: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+#pragma acc kernels create(alwaysin: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+#pragma acc parallel create(alwaysout: V1)
+ for(int i = 5; i < 10;++i);
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc serial create(readonly: V1)
+ for(int i = 5; i < 10;++i);
+#pragma acc kernels loop create(zero: V1)
+ for(int i = 5; i < 10;++i);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
index 1bfd4e8af6481..df01c59349665 100644
--- a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
@@ -99,52 +99,52 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global)
+#pragma acc parallel copy(GlobalArray) pcopy(always: PointerParam[Global]) present_or_copy(alwaysin, alwaysout: Global)
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysin, alwaysout
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copyin(GlobalArray) pcopyin(readonly: PointerParam[Global]) present_or_copyin(Global)
+#pragma acc parallel copyin(GlobalArray) pcopyin(readonly: PointerParam[Global]) present_or_copyin(always, alwaysin: Global)
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global)
+#pragma acc parallel copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(always, alwaysin: Global)
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
@@ -155,7 +155,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -329,15 +329,15 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
+#pragma acc parallel copy(t) pcopy(always: NTTP, u) present_or_copy(alwaysin, alwaysout: u[0:t])
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysin, alwaysout
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -346,15 +346,15 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copyin(t) pcopyin(readonly:NTTP, u) present_or_copyin(u[0:t])
+#pragma acc parallel copyin(t) pcopyin(readonly:NTTP, u) present_or_copyin(always, alwaysin: u[0:t])
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -363,15 +363,15 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-#pragma acc parallel copyout(t) pcopyout(zero:NTTP, u) present_or_copyout(u[0:t])
+#pragma acc parallel copyout(t) pcopyout(zero:NTTP, u) present_or_copyout(always, alwaysin: u[0:t])
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: always, alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -385,7 +385,7 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_create clause
@@ -529,16 +529,16 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-//#pragma acc parallel copy(t) pcopy(NTTP, u) copy_or_present(u[0:t])
+//#pragma acc parallel copy(t) pcopy(always: NTTP, u) present_or_copy(alwaysin, alwaysout: u[0:t])
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysin, alwaysout
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
@@ -549,16 +549,16 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-//#pragma acc parallel copyin(t) pcopyin(readonly:NTTP, u) present_or_copyin(u[0:t])
+//#pragma acc parallel copyin(t) pcopyin(readonly:NTTP, u) present_or_copyin(always, alwaysin: u[0:t])
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
@@ -569,16 +569,16 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
-//#pragma acc parallel copyout(t) pcopyout(zero:NTTP, u) present_or_copyout(u[0:t])
+// #pragma acc parallel copyout(t) pcopyout(zero:NTTP, u) present_or_copyout(always, alwaysin: u[0:t])
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: always, alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
@@ -593,7 +593,7 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/data-construct-copy-ast.cpp b/clang/test/SemaOpenACC/data-construct-copy-ast.cpp
index de067f00a2b29..8c0a12f244257 100644
--- a/clang/test/SemaOpenACC/data-construct-copy-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-copy-ast.cpp
@@ -14,18 +14,18 @@ void NormalUses(float *PointerParam) {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt
-#pragma acc data copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global)
+#pragma acc data copy(GlobalArray) pcopy(always, alwaysin: PointerParam[Global]) present_or_copy(alwaysout: Global)
;
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopy clause
+ // CHECK-NEXT: pcopy clause modifiers: always, alwaysin
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysout
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: NullStmt
}
@@ -40,15 +40,15 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc data copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
+#pragma acc data copy(always: t) pcopy(NTTP, u) present_or_copy(alwaysin, alwaysout: u[0:t])
;
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause modifiers: always
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: pcopy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysin, alwaysout
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -69,14 +69,14 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause modifiers: always
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: pcopy clause
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copy clause
+ // CHECK-NEXT: present_or_copy clause modifiers: alwaysin, alwaysout
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
diff --git a/clang/test/SemaOpenACC/data-construct-copy-clause.c b/clang/test/SemaOpenACC/data-construct-copy-clause.c
index 882a0bc87e003..0b2b0534073ed 100644
--- a/clang/test/SemaOpenACC/data-construct-copy-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copy-clause.c
@@ -67,3 +67,19 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc host_data present_or_copy(LocalInt)
;
}
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc data copy(always, alwaysin, alwaysout, zero, readonly: V1)
+ ;
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+#pragma acc data copy(readonly: V1)
+ ;
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc data copy(zero: V1)
+ ;
+#pragma acc data copy(always, alwaysin, alwaysout: V1)
+;
+}
+
diff --git a/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp b/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp
index fd21d60c84431..a3c8e7a36f9f8 100644
--- a/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp
@@ -19,7 +19,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -29,17 +29,17 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: NullStmt
-#pragma acc enter data copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global)
+#pragma acc enter data copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(readonly, always: Global)
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
}
@@ -54,15 +54,15 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc data copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
+#pragma acc data copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(readonly, always: u[0:t])
;
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, readonly
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -73,7 +73,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyin clause
@@ -98,12 +98,12 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copyin clause
+ // CHECK-NEXT: present_or_copyin clause modifiers: always, readonly
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
@@ -115,7 +115,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyin clause : readonly
+ // CHECK-NEXT: pcopyin clause modifiers: readonly
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/data-construct-copyin-clause.c b/clang/test/SemaOpenACC/data-construct-copyin-clause.c
index 370cc7000f8d8..edc3f0a2e91fe 100644
--- a/clang/test/SemaOpenACC/data-construct-copyin-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copyin-clause.c
@@ -58,7 +58,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data copyin((float)ArrayParam[2])
;
- // expected-error at +2{{invalid tag 'invalid' on 'copyin' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyin' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data copyin(invalid:(float)ArrayParam[2])
;
@@ -71,3 +71,24 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc host_data pcopyin(LocalInt)
;
}
+
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc data copyin(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+#pragma acc data copyin(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc data copyin(zero: V1)
+#pragma acc data copyin(always, alwaysin, readonly: V1)
+
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc enter data copyin(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+#pragma acc enter data copyin(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc enter data copyin(zero: V1)
+#pragma acc enter data copyin(always, alwaysin, readonly: V1)
+}
diff --git a/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp b/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp
index 38e6e7b476fe5..069ced7de83d8 100644
--- a/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp
@@ -19,7 +19,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -29,17 +29,17 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: NullStmt
-#pragma acc exit data copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global)
+#pragma acc exit data copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(always, zero: Global)
// CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: always, zero
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
}
@@ -54,15 +54,15 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt
-#pragma acc data copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
+#pragma acc data copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(alwaysin: u[0:t])
;
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
@@ -73,7 +73,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyout clause
@@ -98,12 +98,12 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
- // CHECK-NEXT: present_or_copyout clause
+ // CHECK-NEXT: present_or_copyout clause modifiers: alwaysin
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
@@ -115,7 +115,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcopyout clause : zero
+ // CHECK-NEXT: pcopyout clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/data-construct-copyout-clause.c b/clang/test/SemaOpenACC/data-construct-copyout-clause.c
index 0f9d5f2ad5c83..8d137e093db0e 100644
--- a/clang/test/SemaOpenACC/data-construct-copyout-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copyout-clause.c
@@ -58,7 +58,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data copyout((float)ArrayParam[2])
;
- // expected-error at +2{{invalid tag 'invalid' on 'copyout' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'copyout' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data copyout(invalid:(float)ArrayParam[2])
;
@@ -71,3 +71,25 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc host_data pcopyout(LocalInt)
;
}
+
+void ModList() {
+ int V1;
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc data copyout(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+#pragma acc data copyout(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc data copyout(readonly: V1)
+#pragma acc data copyout(always, alwaysin, zero: V1)
+
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc exit data copyout(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+#pragma acc exit data copyout(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc exit data copyout(readonly: V1)
+#pragma acc exit data copyout(always, alwaysin, zero: V1)
+}
+
diff --git a/clang/test/SemaOpenACC/data-construct-create-ast.cpp b/clang/test/SemaOpenACC/data-construct-create-ast.cpp
index 623d44aac43f9..a147125aff29b 100644
--- a/clang/test/SemaOpenACC/data-construct-create-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-create-ast.cpp
@@ -19,7 +19,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -33,7 +33,7 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
@@ -59,7 +59,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_create clause
@@ -73,7 +73,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_create clause
@@ -98,7 +98,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCDataConstruct{{.*}} data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
@@ -115,7 +115,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
- // CHECK-NEXT: pcreate clause : zero
+ // CHECK-NEXT: pcreate clause modifiers: zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
diff --git a/clang/test/SemaOpenACC/data-construct-create-clause.c b/clang/test/SemaOpenACC/data-construct-create-clause.c
index 4972bdca4b85d..e49d53b17ee82 100644
--- a/clang/test/SemaOpenACC/data-construct-create-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-create-clause.c
@@ -58,7 +58,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data create((float)ArrayParam[2])
;
- // expected-error at +2{{invalid tag 'invalid' on 'create' clause}}
+ // expected-error at +2{{unknown modifier 'invalid' in OpenACC modifier-list on 'create' clause}}
// expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc data create(invalid:(float)ArrayParam[2])
;
@@ -71,3 +71,36 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc host_data pcreate(LocalInt)
;
}
+
+void ModList() {
+ int V1;
+ // expected-error at +4{{OpenACC 'always' modifier not valid on 'create' clause}}
+ // expected-error at +3{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc data create(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc data create(always: V1)
+ // expected-error at +1{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+#pragma acc data create(alwaysin: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+#pragma acc data create(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc data create(readonly: V1)
+#pragma acc data create(zero: V1)
+
+ // expected-error at +4{{OpenACC 'always' modifier not valid on 'create' clause}}
+ // expected-error at +3{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc enter data create(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc enter data create(always: V1)
+ // expected-error at +1{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+#pragma acc enter data create(alwaysin: V1)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+#pragma acc enter data create(alwaysout: V1)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc enter data create(readonly: V1)
+#pragma acc enter data create(zero: V1)
+}
diff --git a/clang/test/SemaOpenACC/declare-construct-ast.cpp b/clang/test/SemaOpenACC/declare-construct-ast.cpp
index ab49c9e42ea4e..54b40ff6e93de 100644
--- a/clang/test/SemaOpenACC/declare-construct-ast.cpp
+++ b/clang/test/SemaOpenACC/declare-construct-ast.cpp
@@ -11,11 +11,11 @@ int *Global;
// CHECK: VarDecl{{.*}}Global 'int *'
int GlobalArray[5];
// CHECK-NEXT: VarDecl{{.*}}GlobalArray 'int[5]'
-#pragma acc declare deviceptr(Global), copyin(GlobalArray)
+#pragma acc declare deviceptr(Global), copyin(readonly, always: GlobalArray)
// CHECK-NEXT: OpenACCDeclareDecl
// CHECK-NEXT: deviceptr clause
// CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int *'
-// CHECK-NEXT: copyin clause
+// CHECK-NEXT: copyin clause modifiers: always, readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'GlobalArray' 'int[5]'
int *Global1;
@@ -162,12 +162,12 @@ struct DependentStruct {
static constexpr T StaticMemArray2[5] = {};
// CHECK-NEXT: VarDecl{{.*}} StaticMemArray2 'const T[5]'
// CHECK-NEXT: InitListExpr{{.*}}'void'
-#pragma acc declare copyin(StaticMem, StaticMemArray) create(StaticMem2, StaticMemArray2)
+#pragma acc declare copyin(StaticMem, StaticMemArray) create(zero: StaticMem2, StaticMemArray2)
// CHECK-NEXT: OpenACCDeclareDecl
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMem' 'const T'
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMemArray' 'const T[5]'
- // CHECK-NEXT: create clause
+ // CHECK-NEXT: create clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMem2' 'const T'
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMemArray2' 'const T[5]'
@@ -189,14 +189,14 @@ struct DependentStruct {
U LocalArray2[5];
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} LocalArray2 'U[5]'
-#pragma acc declare copy(Arg, Local, LocalArray) copyout(Arg2, Local2, LocalArray2)
+#pragma acc declare copy(always, alwaysin: Arg, Local, LocalArray) copyout(zero: Arg2, Local2, LocalArray2)
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: OpenACCDeclareDecl
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'Arg' 'U'
// CHECK-NEXT: DeclRefExpr{{.*}}'Local' 'T'
// CHECK-NEXT: DeclRefExpr{{.*}}'LocalArray' 'U[5]'
- // CHECK-NEXT: copyout clause
+ // CHECK-NEXT: copyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'Arg2' 'U'
// CHECK-NEXT: DeclRefExpr{{.*}}'Local2' 'T'
// CHECK-NEXT: DeclRefExpr{{.*}}'LocalArray2' 'U[5]'
@@ -251,7 +251,7 @@ struct DependentStruct {
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMem' 'const int'
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMemArray' 'const int[5]'
-// CHECK-NEXT: create clause
+// CHECK-NEXT: create clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMem2' 'const int'
// CHECK-NEXT: DeclRefExpr{{.*}}'StaticMemArray2' 'const int[5]'
@@ -279,11 +279,11 @@ struct DependentStruct {
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: OpenACCDeclareDecl
-// CHECK-NEXT: copy clause
+// CHECK-NEXT: copy clause modifiers: always, alwaysin
// CHECK-NEXT: DeclRefExpr{{.*}}'Arg' 'float'
// CHECK-NEXT: DeclRefExpr{{.*}}'Local' 'int'
// CHECK-NEXT: DeclRefExpr{{.*}}'LocalArray' 'float[5]'
-// CHECK-NEXT: copyout clause
+// CHECK-NEXT: copyout clause modifiers: zero
// CHECK-NEXT: DeclRefExpr{{.*}}'Arg2' 'float'
// CHECK-NEXT: DeclRefExpr{{.*}}'Local2' 'int'
// CHECK-NEXT: DeclRefExpr{{.*}}'LocalArray2' 'float[5]'
diff --git a/clang/test/SemaOpenACC/declare-construct.cpp b/clang/test/SemaOpenACC/declare-construct.cpp
index a1fed096635fa..25038b5bf242c 100644
--- a/clang/test/SemaOpenACC/declare-construct.cpp
+++ b/clang/test/SemaOpenACC/declare-construct.cpp
@@ -306,3 +306,48 @@ struct Struct2 {
}
};
+void ModList() {
+ int V1, V2, V3, V4, V5, V6, V7, V8, V9, V10,
+ V11, V12, V13, V14, V15, V16, V17, V18;
+ // expected-error at +2{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc declare copy(always, alwaysin, alwaysout, zero, readonly: V1)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copy' clause}}
+#pragma acc declare copy(readonly: V2)
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copy' clause}}
+#pragma acc declare copy(zero: V3)
+#pragma acc declare copy(always, alwaysin, alwaysout: V4)
+
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc declare copyin(always, alwaysin, alwaysout, zero, readonly: V5)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyin' clause}}
+#pragma acc declare copyin(alwaysout: V6)
+ // expected-error at +1{{OpenACC 'zero' modifier not valid on 'copyin' clause}}
+#pragma acc declare copyin(zero: V7)
+#pragma acc declare copyin(always, alwaysin, readonly: V8)
+
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc declare copyout(always, alwaysin, alwaysout, zero, readonly: V9)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'copyout' clause}}
+#pragma acc declare copyout(alwaysout: V10)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'copyout' clause}}
+#pragma acc declare copyout(readonly: V11)
+#pragma acc declare copyout(always, alwaysin, zero: V12)
+
+ // expected-error at +4{{OpenACC 'always' modifier not valid on 'create' clause}}
+ // expected-error at +3{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+ // expected-error at +2{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc declare create(always, alwaysin, alwaysout, zero, readonly: V13)
+ // expected-error at +1{{OpenACC 'always' modifier not valid on 'create' clause}}
+#pragma acc declare create(always: V14)
+ // expected-error at +1{{OpenACC 'alwaysin' modifier not valid on 'create' clause}}
+#pragma acc declare create(alwaysin: V15)
+ // expected-error at +1{{OpenACC 'alwaysout' modifier not valid on 'create' clause}}
+#pragma acc declare create(alwaysout: V16)
+ // expected-error at +1{{OpenACC 'readonly' modifier not valid on 'create' clause}}
+#pragma acc declare create(readonly: V17)
+#pragma acc declare create(zero: V18)
+}
More information about the cfe-commits
mailing list