14#ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
15#define LLVM_CLANG_SEMA_SEMAOPENACC_H
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Support/Compiler.h"
37 struct ComputeConstructInfo {
45 } ActiveComputeConstructInfo;
47 bool isInComputeConstruct()
const {
55 struct LoopCheckingInfo {
59 LLVM_PREFERRED_TYPE(
bool)
60 unsigned TopLevelLoopSeen : 1;
64 LLVM_PREFERRED_TYPE(
bool)
65 unsigned CurLevelHasLoopAlready : 1;
67 } LoopInfo{
false,
false};
76 struct CollapseCheckingInfo {
84 std::optional<llvm::APSInt> CurCollapseCount;
89 bool CollapseDepthSatisfied =
true;
98 struct TileCheckingInfo {
104 std::optional<unsigned> CurTileCount;
109 bool TileDepthSatisfied =
true;
125 struct ForStmtBeginChecker {
128 bool IsRangeFor =
false;
129 std::optional<const CXXForRangeStmt *> RangeFor =
nullptr;
130 const Stmt *Init =
nullptr;
131 bool InitChanged =
false;
132 std::optional<const Stmt *> Cond =
nullptr;
133 std::optional<const Stmt *> Inc =
nullptr;
135 bool AlreadyChecked =
false;
138 std::optional<const CXXForRangeStmt *> S)
139 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(
true), RangeFor(S) {}
142 const Stmt *I,
bool InitChanged,
143 std::optional<const Stmt *>
C,
144 std::optional<const Stmt *> Inc)
145 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(
false), Init(I),
146 InitChanged(InitChanged), Cond(
C), Inc(Inc) {}
159 void ForStmtBeginHelper(
SourceLocation ForLoc, ForStmtBeginChecker &
C);
163 return ActiveComputeConstructInfo;
208 struct DefaultDetails {
212 struct ConditionDetails {
216 struct IntExprDetails {
220 struct VarListDetails {
232 struct DeviceTypeDetails {
235 struct ReductionDetails {
240 struct CollapseDetails {
250 std::variant<std::monostate, DefaultDetails, ConditionDetails,
251 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
252 ReductionDetails, CollapseDetails, GangDetails>
253 Details = std::monostate{};
258 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
272 "Parsed clause is not a default clause");
273 return std::get<DefaultDetails>(Details).DefaultClauseKind;
284 "Parsed clause kind does not have a condition expr");
289 std::holds_alternative<std::monostate>(Details))
292 return std::get<ConditionDetails>(Details).ConditionExpr;
305 "Parsed clause kind does not have a int exprs");
313 std::holds_alternative<std::monostate>(Details))
315 return std::get<IntExprDetails>(Details).IntExprs.size();
320 "Parsed clause kind does not have a queues location");
322 if (std::holds_alternative<std::monostate>(Details))
325 return std::get<WaitDetails>(Details).QueuesLoc;
330 "Parsed clause kind does not have a device number expr");
332 if (std::holds_alternative<std::monostate>(Details))
335 return std::get<WaitDetails>(Details).DevNumExpr;
340 "Parsed clause kind does not have a queue id expr list");
342 if (std::holds_alternative<std::monostate>(Details))
345 return std::get<WaitDetails>(Details).QueueIdExprs;
359 "Parsed clause kind does not have a int exprs");
364 if (std::holds_alternative<std::monostate>(Details))
366 return std::get<GangDetails>(Details).IntExprs;
369 return std::get<IntExprDetails>(Details).IntExprs;
377 return std::get<ReductionDetails>(Details).Op;
382 "Parsed clause kind does not have gang kind");
385 if (std::holds_alternative<std::monostate>(Details))
387 return std::get<GangDetails>(Details).GangKinds;
413 "Parsed clause kind does not have a var-list");
416 return std::get<ReductionDetails>(Details).VarList;
418 return std::get<VarListDetails>(Details).VarList;
429 "Only copyin accepts 'readonly:' tag");
430 return std::get<VarListDetails>(Details).IsReadOnly;
440 "Only copyout/create accepts 'zero' tag");
441 return std::get<VarListDetails>(Details).IsZero;
446 "Only 'collapse' has a force tag");
447 return std::get<CollapseDetails>(Details).IsForce;
452 "Only 'collapse' has a loop count");
453 return std::get<CollapseDetails>(Details).LoopCount;
459 "Only 'device_type'/'dtype' has a device-type-arg list");
460 return std::get<DeviceTypeDetails>(Details).Archs;
468 "Parsed clause is not a default clause");
469 Details = DefaultDetails{DefKind};
476 "Parsed clause kind does not have a condition expr");
481 "Condition expression type not scalar/dependent");
483 Details = ConditionDetails{ConditionExpr};
496 "Parsed clause kind does not have a int exprs");
497 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
509 "Parsed clause kind does not have a int exprs");
510 Details = IntExprDetails{std::move(IntExprs)};
516 "Parsed Clause kind does not have gang details");
517 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
519 Details = GangDetails{{GKs.begin(), GKs.end()},
520 {IntExprs.begin(), IntExprs.end()}};
526 "Parsed Clause kind does not have gang details");
527 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
529 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
555 "Parsed clause kind does not have a var-list");
559 "readonly: tag only valid on copyin");
566 "zero: tag only valid on copyout/create");
568 VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
594 "Parsed clause kind does not have a var-list");
598 "readonly: tag only valid on copyin");
605 "zero: tag only valid on copyout/create");
606 Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
612 "reduction details only valid on reduction");
613 Details = ReductionDetails{Op, std::move(VarList)};
619 "Parsed clause kind does not have a wait-details");
620 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
626 "Only 'device_type'/'dtype' has a device-type-arg list");
627 Details = DeviceTypeDetails{std::move(Archs)};
632 "Only 'collapse' has collapse details");
633 Details = CollapseDetails{IsForce, LoopCount};
646 const Stmt *RangeFor);
651 const Stmt *Second,
const Stmt *Third);
654 const Stmt *Second,
const Stmt *OldThird,
663 OpenACCParsedClause &Clause);
766 LoopCheckingInfo OldLoopInfo;
767 CollapseCheckingInfo OldCollapseInfo;
768 TileCheckingInfo OldTileInfo;
773 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
774 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
775 PreserveDepth(PreserveDepth) {}
780 bool CollapseDepthSatisified =
781 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
782 : OldCollapseInfo.CollapseDepthSatisfied;
783 bool TileDepthSatisfied = PreserveDepth
784 ? SemaRef.TileInfo.TileDepthSatisfied
785 : OldTileInfo.TileDepthSatisfied;
786 bool CurLevelHasLoopAlready =
787 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
788 : OldLoopInfo.CurLevelHasLoopAlready;
790 SemaRef.LoopInfo = OldLoopInfo;
791 SemaRef.CollapseInfo = OldCollapseInfo;
792 SemaRef.TileInfo = OldTileInfo;
794 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
795 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
796 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
805 ComputeConstructInfo OldActiveComputeConstructInfo;
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines some OpenACC-specific enums and functions.
Defines the clang::SourceLocation class and associated facilities.
This file defines OpenACC AST classes for statement-level contructs.
This represents one expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
This is the base type for all OpenACC Clauses.
Represents a 'collapse' clause on a 'loop' construct.
Helper type for the registration/assignment of constructs that need to 'know' about their parent cons...
void SetTileInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
void SetCollapseInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
Helper type to restore the state of various 'loop' constructs when we run into a loop (for,...
LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth=true)
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
ArrayRef< Expr * > getIntExprs()
ArrayRef< Expr * > getQueueIdExprs() const
OpenACCDirectiveKind getDirectiveKind() const
ArrayRef< OpenACCGangKind > getGangKinds() const
OpenACCParsedClause(OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
OpenACCReductionOperator getReductionOp() const
SourceLocation getEndLoc() const
void setLParenLoc(SourceLocation EndLoc)
void setConditionDetails(Expr *ConditionExpr)
void setCollapseDetails(bool IsForce, Expr *LoopCount)
OpenACCClauseKind getClauseKind() const
void setGangDetails(ArrayRef< OpenACCGangKind > GKs, ArrayRef< Expr * > IntExprs)
const Expr * getConditionExpr() const
SourceLocation getLParenLoc() const
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
void setIntExprDetails(llvm::SmallVector< Expr * > &&IntExprs)
void setReductionDetails(OpenACCReductionOperator Op, llvm::SmallVector< Expr * > &&VarList)
Expr * getConditionExpr()
ArrayRef< Expr * > getVarList() const
SourceLocation getBeginLoc() const
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
SourceLocation getQueuesLoc() const
void setVarListDetails(llvm::SmallVector< Expr * > &&VarList, bool IsReadOnly, bool IsZero)
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Expr * getDevNumExpr() const
ArrayRef< Expr * > getVarList()
unsigned getNumIntExprs() const
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
void setEndLoc(SourceLocation EndLoc)
ArrayRef< Expr * > getIntExprs() const
Expr * getLoopCount() const
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
void setDeviceTypeDetails(llvm::SmallVector< DeviceTypeArgument > &&Archs)
void setGangDetails(llvm::SmallVector< OpenACCGangKind > &&GKs, llvm::SmallVector< Expr * > &&IntExprs)
OpenACCDefaultClauseKind getDefaultClauseKind() const
ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ComputeConstructInfo & getActiveComputeConstructInfo()
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
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'.
void ActOnWhileStmt(SourceLocation WhileLoc)
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
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 CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
ExprResult CheckCollapseLoopCount(Expr *LoopCount)
Checks the loop depth value for a collapse clause.
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)
std::pair< IdentifierInfo *, SourceLocation > DeviceTypeArgument
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
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.
ExprResult CheckTileSizeExpr(Expr *SizeExpr)
Checks a single size expr for a tile clause.
Sema - This implements semantic analysis and AST building for C.
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)
Stmt - This represents one statement.
bool isScalarType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Gang
'gang' clause, allowed on 'loop' and Combined constructs.
@ Wait
'wait' clause, allowed on Compute, Data, 'update', and Combined constructs.
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ PCopyOut
'copyout' clause alias 'pcopyout'. Preserved for diagnostic purposes.
@ VectorLength
'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...
@ Async
'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined constructs.
@ PresentOrCreate
'create' clause alias 'present_or_create'.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ PresentOrCopy
'copy' clause alias 'present_or_copy'. Preserved for diagnostic purposes.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Worker
'worker' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ DefaultAsync
'default_async' clause, allowed on 'set' construct.
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ 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.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ PresentOrCopyOut
'copyout' clause alias 'present_or_copyout'.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ PCopy
'copy' clause alias 'pcopy'. Preserved for diagnostic purposes.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ PCopyIn
'copyin' clause alias 'pcopyin'. Preserved for diagnostic purposes.
@ PCreate
'create' clause alias 'pcreate'. Preserved for diagnostic purposes.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ DType
'dtype' clause, an alias for 'device_type', stored separately for diagnostic purposes.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ Detach
'detach' clause, allowed on the 'exit data' construct.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ PresentOrCopyIn
'copyin' clause alias 'present_or_copyin'.
If there is a current 'active' loop construct with a 'gang' clause on a 'kernel' construct,...
OpenACCDirectiveKind DirKind
If there is a current 'active' loop construct that does NOT have a 'seq' clause on it,...
OpenACCDirectiveKind Kind