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);
234 bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
235 SourceLocation ClauseLoc,
237 bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
238 SourceLocation ClauseLoc,
241 OpenACCPrivateRecipe CreatePrivateInitRecipe(
const Expr *VarExpr);
242 OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(
const Expr *VarExpr);
243 OpenACCReductionRecipe
244 CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator,
245 const Expr *VarExpr);
249 return ActiveComputeConstructInfo;
259 } LoopGangClauseOnKernel;
279 } LoopWithoutSeqInfo;
294 struct DefaultDetails {
298 struct ConditionDetails {
302 struct IntExprDetails {
306 struct VarListDetails {
317 struct DeviceTypeDetails {
320 struct ReductionDetails {
325 struct CollapseDetails {
335 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
339 std::variant<std::monostate, DefaultDetails, ConditionDetails,
340 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
341 ReductionDetails, CollapseDetails, GangDetails, BindDetails>
342 Details = std::monostate{};
347 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
361 "Parsed clause is not a default clause");
362 return std::get<DefaultDetails>(Details).DefaultClauseKind;
373 "Parsed clause kind does not have a condition expr");
378 std::holds_alternative<std::monostate>(Details))
381 return std::get<ConditionDetails>(Details).ConditionExpr;
394 "Parsed clause kind does not have a int exprs");
402 std::holds_alternative<std::monostate>(Details))
404 return std::get<IntExprDetails>(Details).IntExprs.size();
409 "Parsed clause kind does not have a queues location");
411 if (std::holds_alternative<std::monostate>(Details))
414 return std::get<WaitDetails>(Details).QueuesLoc;
419 "Parsed clause kind does not have a device number expr");
421 if (std::holds_alternative<std::monostate>(Details))
424 return std::get<WaitDetails>(Details).DevNumExpr;
429 "Parsed clause kind does not have a queue id expr list");
431 if (std::holds_alternative<std::monostate>(Details))
434 return std::get<WaitDetails>(Details).QueueIdExprs;
448 "Parsed clause kind does not have a int exprs");
453 if (std::holds_alternative<std::monostate>(Details))
455 return std::get<GangDetails>(Details).IntExprs;
458 return std::get<IntExprDetails>(Details).IntExprs;
466 return std::get<ReductionDetails>(Details).Op;
471 "Parsed clause kind does not have gang kind");
474 if (std::holds_alternative<std::monostate>(Details))
476 return std::get<GangDetails>(Details).GangKinds;
508 "Parsed clause kind does not have a var-list");
511 return std::get<ReductionDetails>(Details).VarList;
513 return std::get<VarListDetails>(Details).VarList;
521 return std::get<VarListDetails>(Details).ModifierKind;
526 "Only 'collapse' has a force tag");
527 return std::get<CollapseDetails>(Details).IsForce;
532 "Only 'collapse' has a loop count");
533 return std::get<CollapseDetails>(Details).LoopCount;
539 "Only 'device_type'/'dtype' has a device-type-arg list");
540 return std::get<DeviceTypeDetails>(Details).Archs;
543 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
546 "Only 'bind' has bind details");
547 return std::get<BindDetails>(Details).Argument;
555 "Parsed clause is not a default clause");
556 Details = DefaultDetails{DefKind};
563 "Parsed clause kind does not have a condition expr");
568 "Condition expression type not scalar/dependent");
570 Details = ConditionDetails{ConditionExpr};
583 "Parsed clause kind does not have a int exprs");
584 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
596 "Parsed clause kind does not have a int exprs");
597 Details = IntExprDetails{std::move(IntExprs)};
603 "Parsed Clause kind does not have gang details");
604 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
606 Details = GangDetails{{GKs.begin(), GKs.end()},
607 {IntExprs.begin(), IntExprs.end()}};
613 "Parsed Clause kind does not have gang details");
614 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
616 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
648 "Parsed clause kind does not have a var-list");
662 "Modifier Kind only valid on copy, copyin, copyout, create");
663 Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
695 "Parsed clause kind does not have a var-list");
709 "Modifier Kind only valid on copy, copyin, copyout, create");
710 Details = VarListDetails{std::move(VarList), ModKind};
716 "reduction details only valid on reduction");
717 Details = ReductionDetails{Op, std::move(VarList)};
723 "Parsed clause kind does not have a wait-details");
724 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
730 "Only 'device_type'/'dtype' has a device-type-arg list");
731 Details = DeviceTypeDetails{std::move(Archs)};
736 "Only 'collapse' has collapse details");
737 Details = CollapseDetails{IsForce, LoopCount};
741 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
744 "Only 'bind' has bind details");
745 Details = BindDetails{Arg};
758 const Stmt *RangeFor);
763 const Stmt *Second,
const Stmt *Third);
766 const Stmt *Second,
const Stmt *OldThird,
775 OpenACCParsedClause &Clause);
849 Decl *NextParsedDecl);
856 OpenACCRoutineDeclAttr *
857 mergeRoutineDeclAttr(
const OpenACCRoutineDeclAttr &Old);
881 void ActOnInvalidParseVar();
890 void ActOnVariableDeclarator(
VarDecl *VD);
962 LoopCheckingInfo OldLoopInfo;
963 CollapseCheckingInfo OldCollapseInfo;
964 TileCheckingInfo OldTileInfo;
969 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
970 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
971 PreserveDepth(PreserveDepth) {}
976 bool CollapseDepthSatisified =
977 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
978 : OldCollapseInfo.CollapseDepthSatisfied;
979 bool TileDepthSatisfied = PreserveDepth
980 ? SemaRef.TileInfo.TileDepthSatisfied
981 : OldTileInfo.TileDepthSatisfied;
982 bool CurLevelHasLoopAlready =
983 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
984 : OldLoopInfo.CurLevelHasLoopAlready;
986 SemaRef.LoopInfo = OldLoopInfo;
987 SemaRef.CollapseInfo = OldCollapseInfo;
988 SemaRef.TileInfo = OldTileInfo;
990 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
991 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
992 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
1001 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, bool DeferHint=false)
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