Skip to content

Commit 6263de9

Browse files
committed
[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.
1 parent ebb0e6c commit 6263de9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+866
-316
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,11 +1087,13 @@ class OpenACCCopyClause final
10871087
: public OpenACCClauseWithVarList,
10881088
private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
10891089
friend TrailingObjects;
1090+
OpenACCModifierKind Modifiers;
10901091

10911092
OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1092-
SourceLocation LParenLoc, ArrayRef<Expr *> VarList,
1093-
SourceLocation EndLoc)
1094-
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc) {
1093+
SourceLocation LParenLoc, OpenACCModifierKind Mods,
1094+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1095+
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1096+
Modifiers(Mods) {
10951097
assert((Spelling == OpenACCClauseKind::Copy ||
10961098
Spelling == OpenACCClauseKind::PCopy ||
10971099
Spelling == OpenACCClauseKind::PresentOrCopy) &&
@@ -1110,20 +1112,23 @@ class OpenACCCopyClause final
11101112
static OpenACCCopyClause *
11111113
Create(const ASTContext &C, OpenACCClauseKind Spelling,
11121114
SourceLocation BeginLoc, SourceLocation LParenLoc,
1113-
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1115+
OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1116+
SourceLocation EndLoc);
1117+
1118+
OpenACCModifierKind getModifierList() const { return Modifiers; }
11141119
};
11151120

11161121
class OpenACCCopyInClause final
11171122
: public OpenACCClauseWithVarList,
11181123
private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
11191124
friend TrailingObjects;
1120-
bool IsReadOnly;
1125+
OpenACCModifierKind Modifiers;
11211126

11221127
OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1123-
SourceLocation LParenLoc, bool IsReadOnly,
1128+
SourceLocation LParenLoc, OpenACCModifierKind Mods,
11241129
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
11251130
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1126-
IsReadOnly(IsReadOnly) {
1131+
Modifiers(Mods) {
11271132
assert((Spelling == OpenACCClauseKind::CopyIn ||
11281133
Spelling == OpenACCClauseKind::PCopyIn ||
11291134
Spelling == OpenACCClauseKind::PresentOrCopyIn) &&
@@ -1139,24 +1144,25 @@ class OpenACCCopyInClause final
11391144
C->getClauseKind() == OpenACCClauseKind::PCopyIn ||
11401145
C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn;
11411146
}
1142-
bool isReadOnly() const { return IsReadOnly; }
1147+
OpenACCModifierKind getModifierList() const { return Modifiers; }
11431148
static OpenACCCopyInClause *
11441149
Create(const ASTContext &C, OpenACCClauseKind Spelling,
1145-
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly,
1146-
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1150+
SourceLocation BeginLoc, SourceLocation LParenLoc,
1151+
OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1152+
SourceLocation EndLoc);
11471153
};
11481154

11491155
class OpenACCCopyOutClause final
11501156
: public OpenACCClauseWithVarList,
11511157
private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
11521158
friend TrailingObjects;
1153-
bool IsZero;
1159+
OpenACCModifierKind Modifiers;
11541160

11551161
OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1156-
SourceLocation LParenLoc, bool IsZero,
1162+
SourceLocation LParenLoc, OpenACCModifierKind Mods,
11571163
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
11581164
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1159-
IsZero(IsZero) {
1165+
Modifiers(Mods) {
11601166
assert((Spelling == OpenACCClauseKind::CopyOut ||
11611167
Spelling == OpenACCClauseKind::PCopyOut ||
11621168
Spelling == OpenACCClauseKind::PresentOrCopyOut) &&
@@ -1172,24 +1178,25 @@ class OpenACCCopyOutClause final
11721178
C->getClauseKind() == OpenACCClauseKind::PCopyOut ||
11731179
C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut;
11741180
}
1175-
bool isZero() const { return IsZero; }
1181+
OpenACCModifierKind getModifierList() const { return Modifiers; }
11761182
static OpenACCCopyOutClause *
11771183
Create(const ASTContext &C, OpenACCClauseKind Spelling,
1178-
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
1179-
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1184+
SourceLocation BeginLoc, SourceLocation LParenLoc,
1185+
OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1186+
SourceLocation EndLoc);
11801187
};
11811188

11821189
class OpenACCCreateClause final
11831190
: public OpenACCClauseWithVarList,
11841191
private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
11851192
friend TrailingObjects;
1186-
bool IsZero;
1193+
OpenACCModifierKind Modifiers;
11871194

11881195
OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1189-
SourceLocation LParenLoc, bool IsZero,
1196+
SourceLocation LParenLoc, OpenACCModifierKind Mods,
11901197
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
11911198
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1192-
IsZero(IsZero) {
1199+
Modifiers(Mods) {
11931200
assert((Spelling == OpenACCClauseKind::Create ||
11941201
Spelling == OpenACCClauseKind::PCreate ||
11951202
Spelling == OpenACCClauseKind::PresentOrCreate) &&
@@ -1205,11 +1212,12 @@ class OpenACCCreateClause final
12051212
C->getClauseKind() == OpenACCClauseKind::PCreate ||
12061213
C->getClauseKind() == OpenACCClauseKind::PresentOrCreate;
12071214
}
1208-
bool isZero() const { return IsZero; }
1215+
OpenACCModifierKind getModifierList() const { return Modifiers; }
12091216
static OpenACCCreateClause *
12101217
Create(const ASTContext &C, OpenACCClauseKind Spelling,
1211-
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
1212-
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1218+
SourceLocation BeginLoc, SourceLocation LParenLoc,
1219+
OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1220+
SourceLocation EndLoc);
12131221
};
12141222

12151223
class OpenACCReductionClause final

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,9 @@ def err_acc_invalid_reduction_operator
14581458
: Error<"invalid reduction operator, expected '+', '*', 'max', 'min', "
14591459
"'&', '|', '^', '&&', or '||'">;
14601460
def err_acc_incorrect_bind_arg : Error<"expected identifier or string literal">;
1461+
def err_acc_modifier
1462+
: Error<"%enum_select<ACCModifier>{%Unknown{unknown}|%Duplicate{duplicate}}"
1463+
"0 modifier %1 in OpenACC modifier-list on '%2' clause">;
14611464

14621465
// OpenMP support.
14631466
def warn_pragma_omp_ignored : Warning<

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13055,6 +13055,8 @@ def warn_acc_confusing_routine_name
1305513055
InGroup<DiagGroup<"openacc-confusing-routine-name">>;
1305613056
def err_acc_decl_for_routine
1305713057
: Error<"expected function or lambda declaration for 'routine' construct">;
13058+
def err_acc_invalid_modifier
13059+
: Error<"OpenACC '%0' modifier not valid on '%1' clause">;
1305813060

1305913061
// AMDGCN builtins diagnostics
1306013062
def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">;

clang/include/clang/Basic/OpenACCKinds.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
#define LLVM_CLANG_BASIC_OPENACCKINDS_H
1616

1717
#include "clang/Basic/Diagnostic.h"
18+
#include "llvm/ADT/BitmaskEnum.h"
1819
#include "llvm/Support/ErrorHandling.h"
1920
#include "llvm/Support/raw_ostream.h"
2021

2122
namespace clang {
23+
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
24+
2225
// Represents the Construct/Directive kind of a pragma directive. Note the
2326
// OpenACC standard is inconsistent between calling these Construct vs
2427
// 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,
619622
OpenACCGangKind Op) {
620623
return printOpenACCGangKind(Out, Op);
621624
}
625+
626+
// Represents the 'modifier' of a 'modifier-list', as applied to copy, copyin,
627+
// copyout, and create. Implemented as a 'bitmask'
628+
enum class OpenACCModifierKind : uint8_t {
629+
Invalid = 0,
630+
Always = 1 << 0,
631+
AlwaysIn = 1 << 1,
632+
AlwaysOut = 1 << 2,
633+
Readonly = 1 << 3,
634+
Zero = 1 << 4,
635+
LLVM_MARK_AS_BITMASK_ENUM(Zero)
636+
};
637+
638+
inline bool isOpenACCModifierBitSet(OpenACCModifierKind List,
639+
OpenACCModifierKind Bit) {
640+
return (List & Bit) != OpenACCModifierKind::Invalid;
641+
}
642+
643+
template <typename StreamTy>
644+
inline StreamTy &printOpenACCModifierKind(StreamTy &Out,
645+
OpenACCModifierKind Mods) {
646+
if (Mods == OpenACCModifierKind::Invalid)
647+
return Out << "<invalid>";
648+
649+
bool First = true;
650+
651+
if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Always)) {
652+
Out << "always";
653+
First = false;
654+
}
655+
656+
if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::AlwaysIn)) {
657+
if (!First)
658+
Out << ", ";
659+
Out << "alwaysin";
660+
First = false;
661+
}
662+
663+
if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::AlwaysOut)) {
664+
if (!First)
665+
Out << ", ";
666+
Out << "alwaysout";
667+
First = false;
668+
}
669+
670+
if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Readonly)) {
671+
if (!First)
672+
Out << ", ";
673+
Out << "readonly";
674+
First = false;
675+
}
676+
677+
if (isOpenACCModifierBitSet(Mods, OpenACCModifierKind::Zero)) {
678+
if (!First)
679+
Out << ", ";
680+
Out << "zero";
681+
First = false;
682+
}
683+
return Out;
684+
}
685+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
686+
OpenACCModifierKind Op) {
687+
return printOpenACCModifierKind(Out, Op);
688+
}
689+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
690+
OpenACCModifierKind Op) {
691+
return printOpenACCModifierKind(Out, Op);
692+
}
622693
} // namespace clang
623694

624695
#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H

clang/include/clang/Parse/Parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,6 +3769,8 @@ class Parser : public CodeCompletionHandler {
37693769
ExprResult ParseOpenACCIDExpression();
37703770
/// Parses the variable list for the `cache` construct.
37713771
OpenACCCacheParseInfo ParseOpenACCCacheVarList();
3772+
/// Parses the 'modifier-list' for copy, copyin, copyout, create.
3773+
OpenACCModifierKind tryParseModifierList(OpenACCClauseKind CK);
37723774

37733775
using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
37743776
/// Parses a single variable in a variable list for OpenACC.

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,7 @@ class SemaOpenACC : public SemaBase {
238238

239239
struct VarListDetails {
240240
SmallVector<Expr *> VarList;
241-
bool IsReadOnly;
242-
bool IsZero;
241+
OpenACCModifierKind ModifierKind;
243242
};
244243

245244
struct WaitDetails {
@@ -451,12 +450,10 @@ class SemaOpenACC : public SemaBase {
451450
return const_cast<OpenACCParsedClause *>(this)->getVarList();
452451
}
453452

454-
bool isReadOnly() const {
455-
return std::get<VarListDetails>(Details).IsReadOnly;
453+
OpenACCModifierKind getModifierList() const {
454+
return std::get<VarListDetails>(Details).ModifierKind;
456455
}
457456

458-
bool isZero() const { return std::get<VarListDetails>(Details).IsZero; }
459-
460457
bool isForce() const {
461458
assert(ClauseKind == OpenACCClauseKind::Collapse &&
462459
"Only 'collapse' has a force tag");
@@ -552,8 +549,8 @@ class SemaOpenACC : public SemaBase {
552549
Details = GangDetails{std::move(GKs), std::move(IntExprs)};
553550
}
554551

555-
void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
556-
bool IsZero) {
552+
void setVarListDetails(ArrayRef<Expr *> VarList,
553+
OpenACCModifierKind ModKind) {
557554
assert((ClauseKind == OpenACCClauseKind::Private ||
558555
ClauseKind == OpenACCClauseKind::NoCreate ||
559556
ClauseKind == OpenACCClauseKind::Present ||
@@ -582,23 +579,25 @@ class SemaOpenACC : public SemaBase {
582579
DirKind == OpenACCDirectiveKind::Update) ||
583580
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
584581
"Parsed clause kind does not have a var-list");
585-
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
582+
assert((ModKind == OpenACCModifierKind::Invalid ||
583+
ClauseKind == OpenACCClauseKind::Copy ||
584+
ClauseKind == OpenACCClauseKind::PCopy ||
585+
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
586+
ClauseKind == OpenACCClauseKind::CopyIn ||
586587
ClauseKind == OpenACCClauseKind::PCopyIn ||
587-
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
588-
"readonly: tag only valid on copyin");
589-
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
588+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
589+
ClauseKind == OpenACCClauseKind::CopyOut ||
590590
ClauseKind == OpenACCClauseKind::PCopyOut ||
591591
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
592592
ClauseKind == OpenACCClauseKind::Create ||
593593
ClauseKind == OpenACCClauseKind::PCreate ||
594594
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
595-
"zero: tag only valid on copyout/create");
596-
Details =
597-
VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
595+
"Modifier Kind only valid on copy, copyin, copyout, create");
596+
Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
598597
}
599598

600-
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
601-
bool IsZero) {
599+
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList,
600+
OpenACCModifierKind ModKind) {
602601
assert((ClauseKind == OpenACCClauseKind::Private ||
603602
ClauseKind == OpenACCClauseKind::NoCreate ||
604603
ClauseKind == OpenACCClauseKind::Present ||
@@ -627,18 +626,21 @@ class SemaOpenACC : public SemaBase {
627626
DirKind == OpenACCDirectiveKind::Update) ||
628627
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
629628
"Parsed clause kind does not have a var-list");
630-
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
629+
assert((ModKind == OpenACCModifierKind::Invalid ||
630+
ClauseKind == OpenACCClauseKind::Copy ||
631+
ClauseKind == OpenACCClauseKind::PCopy ||
632+
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
633+
ClauseKind == OpenACCClauseKind::CopyIn ||
631634
ClauseKind == OpenACCClauseKind::PCopyIn ||
632-
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
633-
"readonly: tag only valid on copyin");
634-
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
635+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
636+
ClauseKind == OpenACCClauseKind::CopyOut ||
635637
ClauseKind == OpenACCClauseKind::PCopyOut ||
636638
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
637639
ClauseKind == OpenACCClauseKind::Create ||
638640
ClauseKind == OpenACCClauseKind::PCreate ||
639641
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
640-
"zero: tag only valid on copyout/create");
641-
Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
642+
"Modifier Kind only valid on copy, copyin, copyout, create");
643+
Details = VarListDetails{std::move(VarList), ModKind};
642644
}
643645

644646
void setReductionDetails(OpenACCReductionOperator Op,
@@ -826,7 +828,8 @@ class SemaOpenACC : public SemaBase {
826828

827829
// Checking for the arguments specific to the declare-clause that need to be
828830
// checked during both phases of template translation.
829-
bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause);
831+
bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
832+
OpenACCModifierKind Mods);
830833

831834
ExprResult ActOnRoutineName(Expr *RoutineName);
832835

0 commit comments

Comments
 (0)