clang 19.0.0git
SemaOpenACC.h
Go to the documentation of this file.
1//===----- SemaOpenACC.h - Semantic Analysis for OpenACC constructs -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file declares semantic analysis for OpenACC constructs and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
15#define LLVM_CLANG_SEMA_SEMAOPENACC_H
16
17#include "clang/AST/DeclGroup.h"
21#include "clang/Sema/SemaBase.h"
22#include <variant>
23
24namespace clang {
25class OpenACCClause;
26
27class SemaOpenACC : public SemaBase {
28public:
29 /// A type to represent all the data for an OpenACC Clause that has been
30 /// parsed, but not yet created/semantically analyzed. This is effectively a
31 /// discriminated union on the 'Clause Kind', with all of the individual
32 /// clause details stored in a std::variant.
35 OpenACCClauseKind ClauseKind;
36 SourceRange ClauseRange;
37 SourceLocation LParenLoc;
38
39 struct DefaultDetails {
40 OpenACCDefaultClauseKind DefaultClauseKind;
41 };
42
43 struct ConditionDetails {
44 Expr *ConditionExpr;
45 };
46
47 struct IntExprDetails {
48 SmallVector<Expr *> IntExprs;
49 };
50
51 struct VarListDetails {
52 SmallVector<Expr *> VarList;
53 };
54
55 std::variant<std::monostate, DefaultDetails, ConditionDetails,
56 IntExprDetails, VarListDetails>
57 Details = std::monostate{};
58
59 public:
61 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
62 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
63
64 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
65
66 OpenACCClauseKind getClauseKind() const { return ClauseKind; }
67
68 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
69
70 SourceLocation getLParenLoc() const { return LParenLoc; }
71
72 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
73
75 assert(ClauseKind == OpenACCClauseKind::Default &&
76 "Parsed clause is not a default clause");
77 return std::get<DefaultDetails>(Details).DefaultClauseKind;
78 }
79
80 const Expr *getConditionExpr() const {
81 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
82 }
83
85 assert((ClauseKind == OpenACCClauseKind::If ||
86 (ClauseKind == OpenACCClauseKind::Self &&
87 DirKind != OpenACCDirectiveKind::Update)) &&
88 "Parsed clause kind does not have a condition expr");
89
90 // 'self' has an optional ConditionExpr, so be tolerant of that. This will
91 // assert in variant otherwise.
92 if (ClauseKind == OpenACCClauseKind::Self &&
93 std::holds_alternative<std::monostate>(Details))
94 return nullptr;
95
96 return std::get<ConditionDetails>(Details).ConditionExpr;
97 }
98
99 unsigned getNumIntExprs() const {
100 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
101 ClauseKind == OpenACCClauseKind::NumWorkers ||
102 ClauseKind == OpenACCClauseKind::VectorLength) &&
103 "Parsed clause kind does not have a int exprs");
104 return std::get<IntExprDetails>(Details).IntExprs.size();
105 }
106
108 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
109 ClauseKind == OpenACCClauseKind::NumWorkers ||
110 ClauseKind == OpenACCClauseKind::VectorLength) &&
111 "Parsed clause kind does not have a int exprs");
112 return std::get<IntExprDetails>(Details).IntExprs;
113 }
114
116 return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
117 }
118
120 assert(ClauseKind == OpenACCClauseKind::Private &&
121 "Parsed clause kind does not have a var-list");
122 return std::get<VarListDetails>(Details).VarList;
123 }
124
126 return const_cast<OpenACCParsedClause *>(this)->getVarList();
127 }
128
129 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
130 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
131
133 assert(ClauseKind == OpenACCClauseKind::Default &&
134 "Parsed clause is not a default clause");
135 Details = DefaultDetails{DefKind};
136 }
137
138 void setConditionDetails(Expr *ConditionExpr) {
139 assert((ClauseKind == OpenACCClauseKind::If ||
140 (ClauseKind == OpenACCClauseKind::Self &&
141 DirKind != OpenACCDirectiveKind::Update)) &&
142 "Parsed clause kind does not have a condition expr");
143 // In C++ we can count on this being a 'bool', but in C this gets left as
144 // some sort of scalar that codegen will have to take care of converting.
145 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
146 ConditionExpr->getType()->isScalarType()) &&
147 "Condition expression type not scalar/dependent");
148
149 Details = ConditionDetails{ConditionExpr};
150 }
151
153 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
154 ClauseKind == OpenACCClauseKind::NumWorkers ||
155 ClauseKind == OpenACCClauseKind::VectorLength) &&
156 "Parsed clause kind does not have a int exprs");
157 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
158 }
160 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
161 ClauseKind == OpenACCClauseKind::NumWorkers ||
162 ClauseKind == OpenACCClauseKind::VectorLength) &&
163 "Parsed clause kind does not have a int exprs");
164 Details = IntExprDetails{std::move(IntExprs)};
165 }
166
168 assert(ClauseKind == OpenACCClauseKind::Private &&
169 "Parsed clause kind does not have a var-list");
170 Details = VarListDetails{{VarList.begin(), VarList.end()}};
171 }
172
174 assert(ClauseKind == OpenACCClauseKind::Private &&
175 "Parsed clause kind does not have a var-list");
176 Details = VarListDetails{std::move(VarList)};
177 }
178 };
179
180 SemaOpenACC(Sema &S);
181
182 /// Called after parsing an OpenACC Clause so that it can be checked.
184 OpenACCParsedClause &Clause);
185
186 /// Called after the construct has been parsed, but clauses haven't been
187 /// parsed. This allows us to diagnose not-implemented, as well as set up any
188 /// state required for parsing the clauses.
190
191 /// Called after the directive, including its clauses, have been parsed and
192 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
193 /// happen before any associated declarations or statements have been parsed.
194 /// This function is only called when we are parsing a 'statement' context.
196
197 /// Called after the directive, including its clauses, have been parsed and
198 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
199 /// happen before any associated declarations or statements have been parsed.
200 /// This function is only called when we are parsing a 'Decl' context.
202 /// Called when we encounter an associated statement for our construct, this
203 /// should check legality of the statement as it appertains to this Construct.
205
206 /// Called after the directive has been completely parsed, including the
207 /// declaration group or associated statement.
209 SourceLocation StartLoc,
210 SourceLocation EndLoc,
212 StmtResult AssocStmt);
213
214 /// Called after the directive has been completely parsed, including the
215 /// declaration group or associated statement.
217
218 /// Called when encountering an 'int-expr' for OpenACC, and manages
219 /// conversions and diagnostics to 'int'.
221 SourceLocation Loc, Expr *IntExpr);
222
223 /// Called when encountering a 'var' for OpenACC, ensures it is actually a
224 /// declaration reference to a variable of the correct type.
225 ExprResult ActOnVar(Expr *VarExpr);
226
227 /// Checks and creates an Array Section used in an OpenACC construct/clause.
229 Expr *LowerBound,
230 SourceLocation ColonLocFirst, Expr *Length,
231 SourceLocation RBLoc);
232};
233
234} // namespace clang
235
236#endif // LLVM_CLANG_SEMA_SEMAOPENACC_H
Defines some OpenACC-specific enums and functions.
Defines the clang::SourceLocation class and associated facilities.
This represents one expression.
Definition: Expr.h:110
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:221
QualType getType() const
Definition: Expr.h:142
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:22
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:33
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:64
OpenACCParsedClause(OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
Definition: SemaOpenACC.h:60
SourceLocation getEndLoc() const
Definition: SemaOpenACC.h:72
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:129
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:138
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:66
const Expr * getConditionExpr() const
Definition: SemaOpenACC.h:80
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:70
void setIntExprDetails(llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:159
void setVarListDetails(ArrayRef< Expr * > VarList)
Definition: SemaOpenACC.h:167
void setVarListDetails(llvm::SmallVector< Expr * > &&VarList)
Definition: SemaOpenACC.h:173
ArrayRef< Expr * > getVarList() const
Definition: SemaOpenACC.h:125
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:68
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:132
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:130
ArrayRef< Expr * > getIntExprs() const
Definition: SemaOpenACC.h:115
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:152
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:74
ExprResult ActOnVar(Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)
Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
void setEnd(SourceLocation e)
bool isScalarType() const
Definition: Type.h:8004
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:164
@ VectorLength
'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ NumGangs
'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
OpenACCDefaultClauseKind
Definition: OpenACCKinds.h:419
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25