14#ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
15#define LLVM_CLANG_SEMA_SEMAOPENACC_H
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/Support/Compiler.h"
42 struct ComputeConstructInfo {
50 } ActiveComputeConstructInfo;
52 bool isInComputeConstruct()
const {
60 struct LoopCheckingInfo {
64 LLVM_PREFERRED_TYPE(
bool)
65 unsigned TopLevelLoopSeen : 1;
69 LLVM_PREFERRED_TYPE(
bool)
70 unsigned CurLevelHasLoopAlready : 1;
72 } LoopInfo{
false,
false};
81 struct CollapseCheckingInfo {
82 const OpenACCCollapseClause *ActiveCollapse =
nullptr;
89 std::optional<llvm::APSInt> CurCollapseCount;
94 bool CollapseDepthSatisfied =
true;
103 struct TileCheckingInfo {
104 OpenACCTileClause *ActiveTile =
nullptr;
109 UnsignedOrNone CurTileCount = std::nullopt;
114 bool TileDepthSatisfied =
true;
125 struct CacheParseInfo {
126 bool ParsingCacheVarList =
false;
127 bool IsInvalidCacheRef =
false;
136 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
140 class ForStmtBeginChecker {
142 SourceLocation ForLoc;
143 bool IsInstantiation =
false;
145 struct RangeForInfo {
146 const CXXForRangeStmt *Uninstantiated =
nullptr;
147 const CXXForRangeStmt *CurrentVersion =
nullptr;
150 RangeForInfo() : Uninstantiated{
nullptr}, CurrentVersion{
nullptr} {}
151 RangeForInfo(
const CXXForRangeStmt *Uninst,
const CXXForRangeStmt *Cur)
152 : Uninstantiated{Uninst}, CurrentVersion{Cur} {}
156 const Stmt *Init =
nullptr;
157 const Stmt *Condition =
nullptr;
158 const Stmt *Increment =
nullptr;
161 struct CheckForInfo {
166 std::variant<RangeForInfo, CheckForInfo> Info;
168 bool AlreadyChecked =
false;
170 void checkRangeFor();
172 bool checkForInit(
const Stmt *InitStmt,
const ValueDecl *&InitVar,
174 bool checkForCond(
const Stmt *CondStmt,
const ValueDecl *InitVar,
176 bool checkForInc(
const Stmt *IncStmt,
const ValueDecl *InitVar,
bool Diag);
182 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
183 const CXXForRangeStmt *RangeFor)
184 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
false),
185 Info(RangeForInfo{
nullptr, RangeFor}) {}
187 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
188 const CXXForRangeStmt *OldRangeFor,
189 const CXXForRangeStmt *RangeFor)
190 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
true),
191 Info(RangeForInfo{OldRangeFor, RangeFor}) {}
193 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
194 const Stmt *
Init,
const Stmt *
Cond,
const Stmt *Inc)
195 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
false),
199 const Stmt *OldInit,
const Stmt *OldCond,
200 const Stmt *OldInc,
const Stmt *
Init,
const Stmt *
Cond,
203 Info(CheckForInfo{{OldInit, OldCond, OldInc}, {
Init,
Cond,
Inc}}) {}
209 void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C);
215 llvm::DenseMap<const clang::DeclaratorDecl *, SourceLocation>
216 DeclareVarReferences;
220 llvm::SmallDenseMap<const clang::FunctionDecl *, SourceLocation>
222 OpenACCRoutineDecl *LastRoutineDecl =
nullptr;
224 void CheckLastRoutineDeclNameConflict(
const NamedDecl *ND);
226 bool DiagnoseRequiredClauses(OpenACCDirectiveKind DK, SourceLocation DirLoc,
229 bool DiagnoseAllowedClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
230 SourceLocation ClauseLoc);
231 bool CreateReductionCombinerRecipe(
232 SourceLocation loc, OpenACCReductionOperator ReductionOperator,
239 bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
240 SourceLocation ClauseLoc,
242 bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
243 SourceLocation ClauseLoc,
246 OpenACCPrivateRecipe CreatePrivateInitRecipe(
const Expr *VarExpr);
247 OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(
const Expr *VarExpr);
248 OpenACCReductionRecipeWithStorage
249 CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator,
250 const Expr *VarExpr);
254 return ActiveComputeConstructInfo;
264 } LoopGangClauseOnKernel;
284 } LoopWithoutSeqInfo;
299 struct DefaultDetails {
303 struct ConditionDetails {
307 struct IntExprDetails {
311 struct VarListDetails {
322 struct DeviceTypeDetails {
325 struct ReductionDetails {
330 struct CollapseDetails {
340 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
344 std::variant<std::monostate, DefaultDetails, ConditionDetails,
345 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
346 ReductionDetails, CollapseDetails, GangDetails, BindDetails>
347 Details = std::monostate{};
352 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
366 "Parsed clause is not a default clause");
367 return std::get<DefaultDetails>(Details).DefaultClauseKind;
378 "Parsed clause kind does not have a condition expr");
383 std::holds_alternative<std::monostate>(Details))
386 return std::get<ConditionDetails>(Details).ConditionExpr;
399 "Parsed clause kind does not have a int exprs");
407 std::holds_alternative<std::monostate>(Details))
409 return std::get<IntExprDetails>(Details).IntExprs.size();
414 "Parsed clause kind does not have a queues location");
416 if (std::holds_alternative<std::monostate>(Details))
419 return std::get<WaitDetails>(Details).QueuesLoc;
424 "Parsed clause kind does not have a device number expr");
426 if (std::holds_alternative<std::monostate>(Details))
429 return std::get<WaitDetails>(Details).DevNumExpr;
434 "Parsed clause kind does not have a queue id expr list");
436 if (std::holds_alternative<std::monostate>(Details))
439 return std::get<WaitDetails>(Details).QueueIdExprs;
453 "Parsed clause kind does not have a int exprs");
458 if (std::holds_alternative<std::monostate>(Details))
460 return std::get<GangDetails>(Details).IntExprs;
463 return std::get<IntExprDetails>(Details).IntExprs;
471 return std::get<ReductionDetails>(Details).Op;
476 "Parsed clause kind does not have gang kind");
479 if (std::holds_alternative<std::monostate>(Details))
481 return std::get<GangDetails>(Details).GangKinds;
513 "Parsed clause kind does not have a var-list");
516 return std::get<ReductionDetails>(Details).VarList;
518 return std::get<VarListDetails>(Details).VarList;
526 return std::get<VarListDetails>(Details).ModifierKind;
531 "Only 'collapse' has a force tag");
532 return std::get<CollapseDetails>(Details).IsForce;
537 "Only 'collapse' has a loop count");
538 return std::get<CollapseDetails>(Details).LoopCount;
544 "Only 'device_type'/'dtype' has a device-type-arg list");
545 return std::get<DeviceTypeDetails>(Details).Archs;
548 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
551 "Only 'bind' has bind details");
552 return std::get<BindDetails>(Details).Argument;
560 "Parsed clause is not a default clause");
561 Details = DefaultDetails{DefKind};
568 "Parsed clause kind does not have a condition expr");
573 "Condition expression type not scalar/dependent");
575 Details = ConditionDetails{ConditionExpr};
588 "Parsed clause kind does not have a int exprs");
589 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
601 "Parsed clause kind does not have a int exprs");
602 Details = IntExprDetails{std::move(IntExprs)};
608 "Parsed Clause kind does not have gang details");
609 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
611 Details = GangDetails{{GKs.begin(), GKs.end()},
612 {IntExprs.begin(), IntExprs.end()}};
618 "Parsed Clause kind does not have gang details");
619 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
621 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
653 "Parsed clause kind does not have a var-list");
667 "Modifier Kind only valid on copy, copyin, copyout, create");
668 Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
700 "Parsed clause kind does not have a var-list");
714 "Modifier Kind only valid on copy, copyin, copyout, create");
715 Details = VarListDetails{std::move(VarList), ModKind};
721 "reduction details only valid on reduction");
722 Details = ReductionDetails{Op, std::move(VarList)};
728 "Parsed clause kind does not have a wait-details");
729 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
735 "Only 'device_type'/'dtype' has a device-type-arg list");
736 Details = DeviceTypeDetails{std::move(Archs)};
741 "Only 'collapse' has collapse details");
742 Details = CollapseDetails{IsForce, LoopCount};
746 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
749 "Only 'bind' has bind details");
750 Details = BindDetails{Arg};
763 const Stmt *RangeFor);
768 const Stmt *Second,
const Stmt *Third);
771 const Stmt *Second,
const Stmt *OldThird,
780 OpenACCParsedClause &Clause);
854 Decl *NextParsedDecl);
861 OpenACCRoutineDeclAttr *
862 mergeRoutineDeclAttr(
const OpenACCRoutineDeclAttr &Old);
886 void ActOnInvalidParseVar();
895 void ActOnVariableDeclarator(
VarDecl *VD);
919 bool CheckReductionVarType(
Expr *VarExpr);
970 LoopCheckingInfo OldLoopInfo;
971 CollapseCheckingInfo OldCollapseInfo;
972 TileCheckingInfo OldTileInfo;
977 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
978 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
979 PreserveDepth(PreserveDepth) {}
984 bool CollapseDepthSatisified =
985 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
986 : OldCollapseInfo.CollapseDepthSatisfied;
987 bool TileDepthSatisfied = PreserveDepth
988 ? SemaRef.TileInfo.TileDepthSatisfied
989 : OldTileInfo.TileDepthSatisfied;
990 bool CurLevelHasLoopAlready =
991 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
992 : OldLoopInfo.CurLevelHasLoopAlready;
994 SemaRef.LoopInfo = OldLoopInfo;
995 SemaRef.CollapseInfo = OldCollapseInfo;
996 SemaRef.TileInfo = OldTileInfo;
998 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
999 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
1000 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
1009 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.
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
A simple pair of identifier info and location.
Wrapper for void* pointer.
This is the base type for all OpenACC Clauses.
A (possibly-)qualified type.
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation, ArrayRef< const OpenACCClause * >, ArrayRef< OpenACCClause * >)
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...
void setVarListDetails(ArrayRef< Expr * > VarList, OpenACCModifierKind ModKind)
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
std::variant< std::monostate, clang::StringLiteral *, IdentifierInfo * > getBindDetails() 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
OpenACCModifierKind getModifierList() const
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 setBindDetails(std::variant< std::monostate, clang::StringLiteral *, IdentifierInfo * > Arg)
void setVarListDetails(llvm::SmallVector< Expr * > &&VarList, OpenACCModifierKind ModKind)
void setDeviceTypeDetails(llvm::SmallVector< DeviceTypeArgument > &&Archs)
void setGangDetails(llvm::SmallVector< OpenACCGangKind > &&GKs, llvm::SmallVector< Expr * > &&IntExprs)
OpenACCDefaultClauseKind getDefaultClauseKind() const
ComputeConstructInfo & getActiveComputeConstructInfo()
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
IdentifierLoc DeviceTypeArgument
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, OpenACCAtomicKind AtKind, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
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.
Stmt - This represents one statement.
bool isScalarType() const
Represents a variable declaration or definition.
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Bind
'bind' clause, allowed on routine constructs.
@ 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'.
@ Link
'link' clause, allowed on 'declare' construct.
@ 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...
@ Host
'host' clause, allowed on 'update' construct.
@ 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.
@ DeviceResident
'device_resident' clause, allowed on the 'declare' construct.
@ 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',...
@ Device
'device' clause, allowed on the 'update' construct.
@ 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'.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
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