17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/bit.h"
29 static_assert(
static_cast<unsigned>(OpenACCClauseKind::Invalid) < 64);
37 constexpr AccClauseSet(std::initializer_list<OpenACCClauseKind> Clauses)
44 return ((Data >>
static_cast<uint64_t>(
C)) & 1) != 0;
51 constexpr bool isEmpty()
const {
return Data == 0; }
53 unsigned popcount()
const {
return llvm::popcount<uint64_t>(Data); }
56struct LLVMClauseLists {
58 AccClauseSet AllowedOnce;
59 AccClauseSet AllowedExclusive;
62struct LLVMDirectiveClauseRelationships {
64 LLVMClauseLists Lists;
71#define GEN_CLANG_DIRECTIVE_CLAUSE_SETS
72#include "llvm/Frontend/OpenACC/ACC.inc"
75LLVMDirectiveClauseRelationships Relations[] =
76#define GEN_CLANG_DIRECTIVE_CLAUSE_MAP
77#include "llvm/Frontend/OpenACC/ACC.inc"
82 auto Res = llvm::find_if(Relations,
83 [=](
const LLVMDirectiveClauseRelationships &Rel) {
84 return Rel.DirKind == DK;
86 assert(Res != std::end(Relations) &&
"Unknown directive kind?");
91std::string getListOfClauses(AccClauseSet
Set) {
95 llvm::raw_string_ostream OS{Output};
97 for (
unsigned I = 0; I < static_cast<unsigned>(OpenACCClauseKind::Invalid);
100 if (!
Set.isSet(CurClause))
103 OS <<
'\'' << CurClause <<
'\'';
105 Set.clearBit(CurClause);
114 if (
Set.popcount() == 1)
125#define VISIT_CLAUSE(NAME)
126#define CLAUSE_ALIAS(ALIAS, NAME, DEPRECATED) \
127 case OpenACCClauseKind::ALIAS: \
128 return OpenACCClauseKind::NAME;
129#include "clang/Basic/OpenACCClauses.def"
138bool SemaOpenACC::DiagnoseRequiredClauses(
144 const LLVMClauseLists &Lists = getListsForDirective(DK);
146 if (Lists.Required.isEmpty())
149 for (
auto *
C : Clauses) {
150 if (Lists.Required.isSet(dealiasClauseKind(
C->getClauseKind())))
154 return Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
155 << DK << getListOfClauses(Lists.Required);
169 const LLVMClauseLists &Lists = getListsForDirective(DK);
170 if (!Lists.AllowedOnce.isSet(CK))
174 return dealiasClauseKind(
C->getClauseKind()) == Dealiased;
177 if (Res == Clauses.end())
180 Diag(ClauseLoc, diag::err_acc_duplicate_clause_disallowed) << DK << CK;
181 Diag((*Res)->getBeginLoc(), diag::note_acc_previous_clause_here) << CK;
193 const LLVMClauseLists &Lists = getListsForDirective(DK);
197 if (!Lists.AllowedExclusive.isSet(Dealiased))
201 if (Lists.AllowedExclusive.isSet(dealiasClauseKind(
C->getClauseKind()))) {
202 Diag(ClauseLoc, diag::err_acc_clause_cannot_combine)
203 << CK <<
C->getClauseKind() << DK;
204 Diag(
C->getBeginLoc(), diag::note_acc_previous_clause_here)
205 <<
C->getClauseKind();
220 const LLVMClauseLists &Lists = getListsForDirective(DK);
223 if (!Lists.Allowed.isSet(Dealiased) && !Lists.AllowedOnce.isSet(Dealiased) &&
224 !Lists.AllowedExclusive.isSet(Dealiased) &&
225 !Lists.Required.isSet(Dealiased))
226 return Diag(ClauseLoc, diag::err_acc_clause_appertainment) << DK << CK;
This file declares semantic analysis for OpenACC constructs and clauses.
This is the base type for all OpenACC Clauses.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation ClauseLoc, ArrayRef< const OpenACCClause * > Clauses)
bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation ClauseLoc, ArrayRef< const OpenACCClause * > Clauses)
Encodes a location in the source.
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
char __ovld __cnfn popcount(char)