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"
50 struct ComputeConstructInfo {
58 } ActiveComputeConstructInfo;
60 bool isInComputeConstruct()
const {
68 struct LoopCheckingInfo {
72 LLVM_PREFERRED_TYPE(
bool)
73 unsigned TopLevelLoopSeen : 1;
77 LLVM_PREFERRED_TYPE(
bool)
78 unsigned CurLevelHasLoopAlready : 1;
80 } LoopInfo{
false,
false};
89 struct CollapseCheckingInfo {
90 const OpenACCCollapseClause *ActiveCollapse =
nullptr;
97 std::optional<llvm::APSInt> CurCollapseCount;
102 bool CollapseDepthSatisfied =
true;
111 struct TileCheckingInfo {
112 OpenACCTileClause *ActiveTile =
nullptr;
117 UnsignedOrNone CurTileCount = std::nullopt;
122 bool TileDepthSatisfied =
true;
133 struct CacheParseInfo {
134 bool ParsingCacheVarList =
false;
135 bool IsInvalidCacheRef =
false;
144 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
148 class ForStmtBeginChecker {
150 SourceLocation ForLoc;
151 bool IsInstantiation =
false;
153 struct RangeForInfo {
154 const CXXForRangeStmt *Uninstantiated =
nullptr;
155 const CXXForRangeStmt *CurrentVersion =
nullptr;
158 RangeForInfo() : Uninstantiated{
nullptr}, CurrentVersion{
nullptr} {}
159 RangeForInfo(
const CXXForRangeStmt *Uninst,
const CXXForRangeStmt *Cur)
160 : Uninstantiated{Uninst}, CurrentVersion{Cur} {}
164 const Stmt *Init =
nullptr;
165 const Stmt *Condition =
nullptr;
166 const Stmt *Increment =
nullptr;
169 struct CheckForInfo {
174 std::variant<RangeForInfo, CheckForInfo> Info;
176 bool AlreadyChecked =
false;
178 void checkRangeFor();
180 bool checkForInit(
const Stmt *InitStmt,
const ValueDecl *&InitVar,
182 bool checkForCond(
const Stmt *CondStmt,
const ValueDecl *InitVar,
184 bool checkForInc(
const Stmt *IncStmt,
const ValueDecl *InitVar,
bool Diag);
190 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
191 const CXXForRangeStmt *RangeFor)
192 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
false),
193 Info(RangeForInfo{
nullptr, RangeFor}) {}
195 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
196 const CXXForRangeStmt *OldRangeFor,
197 const CXXForRangeStmt *RangeFor)
198 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
true),
199 Info(RangeForInfo{OldRangeFor, RangeFor}) {}
201 ForStmtBeginChecker(
SemaOpenACC &SemaRef, SourceLocation ForLoc,
202 const Stmt *
Init,
const Stmt *
Cond,
const Stmt *Inc)
203 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(
false),
207 const Stmt *OldInit,
const Stmt *OldCond,
208 const Stmt *OldInc,
const Stmt *
Init,
const Stmt *
Cond,
211 Info(CheckForInfo{{OldInit, OldCond, OldInc}, {
Init,
Cond,
Inc}}) {}
217 void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C);
223 llvm::DenseMap<const clang::DeclaratorDecl *, SourceLocation>
224 DeclareVarReferences;
228 llvm::SmallDenseMap<const clang::FunctionDecl *, SourceLocation>
230 OpenACCRoutineDecl *LastRoutineDecl =
nullptr;
232 void CheckLastRoutineDeclNameConflict(
const NamedDecl *ND);
234 bool DiagnoseRequiredClauses(OpenACCDirectiveKind DK, SourceLocation DirLoc,
237 bool DiagnoseAllowedClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
238 SourceLocation ClauseLoc);
239 bool CreateReductionCombinerRecipe(
240 SourceLocation loc, OpenACCReductionOperator ReductionOperator,
247 bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
248 SourceLocation ClauseLoc,
250 bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
251 SourceLocation ClauseLoc,
254 OpenACCPrivateRecipe CreatePrivateInitRecipe(
const Expr *VarExpr);
255 OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(
const Expr *VarExpr);
256 OpenACCReductionRecipeWithStorage
257 CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator,
258 const Expr *VarExpr);
262 return ActiveComputeConstructInfo;
272 } LoopGangClauseOnKernel;
292 } LoopWithoutSeqInfo;
307 struct DefaultDetails {
311 struct ConditionDetails {
315 struct IntExprDetails {
319 struct VarListDetails {
330 struct DeviceTypeDetails {
333 struct ReductionDetails {
338 struct CollapseDetails {
348 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
352 std::variant<std::monostate, DefaultDetails, ConditionDetails,
353 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
354 ReductionDetails, CollapseDetails, GangDetails, BindDetails>
355 Details = std::monostate{};
360 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
374 "Parsed clause is not a default clause");
375 return std::get<DefaultDetails>(Details).DefaultClauseKind;
386 "Parsed clause kind does not have a condition expr");
391 std::holds_alternative<std::monostate>(Details))
394 return std::get<ConditionDetails>(Details).ConditionExpr;
407 "Parsed clause kind does not have a int exprs");
415 std::holds_alternative<std::monostate>(Details))
417 return std::get<IntExprDetails>(Details).IntExprs.size();
422 "Parsed clause kind does not have a queues location");
424 if (std::holds_alternative<std::monostate>(Details))
427 return std::get<WaitDetails>(Details).QueuesLoc;
432 "Parsed clause kind does not have a device number expr");
434 if (std::holds_alternative<std::monostate>(Details))
437 return std::get<WaitDetails>(Details).DevNumExpr;
442 "Parsed clause kind does not have a queue id expr list");
444 if (std::holds_alternative<std::monostate>(Details))
447 return std::get<WaitDetails>(Details).QueueIdExprs;
461 "Parsed clause kind does not have a int exprs");
466 if (std::holds_alternative<std::monostate>(Details))
468 return std::get<GangDetails>(Details).IntExprs;
471 return std::get<IntExprDetails>(Details).IntExprs;
479 return std::get<ReductionDetails>(Details).Op;
484 "Parsed clause kind does not have gang kind");
487 if (std::holds_alternative<std::monostate>(Details))
489 return std::get<GangDetails>(Details).GangKinds;
521 "Parsed clause kind does not have a var-list");
524 return std::get<ReductionDetails>(Details).VarList;
526 return std::get<VarListDetails>(Details).VarList;
534 return std::get<VarListDetails>(Details).ModifierKind;
539 "Only 'collapse' has a force tag");
540 return std::get<CollapseDetails>(Details).IsForce;
545 "Only 'collapse' has a loop count");
546 return std::get<CollapseDetails>(Details).LoopCount;
552 "Only 'device_type'/'dtype' has a device-type-arg list");
553 return std::get<DeviceTypeDetails>(Details).Archs;
556 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
559 "Only 'bind' has bind details");
560 return std::get<BindDetails>(Details).Argument;
568 "Parsed clause is not a default clause");
569 Details = DefaultDetails{DefKind};
576 "Parsed clause kind does not have a condition expr");
581 "Condition expression type not scalar/dependent");
583 Details = ConditionDetails{ConditionExpr};
596 "Parsed clause kind does not have a int exprs");
597 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
609 "Parsed clause kind does not have a int exprs");
610 Details = IntExprDetails{std::move(IntExprs)};
616 "Parsed Clause kind does not have gang details");
617 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
619 Details = GangDetails{{GKs.begin(), GKs.end()},
620 {IntExprs.begin(), IntExprs.end()}};
626 "Parsed Clause kind does not have gang details");
627 assert(GKs.size() == IntExprs.size() &&
"Mismatched kind/size?");
629 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
661 "Parsed clause kind does not have a var-list");
675 "Modifier Kind only valid on copy, copyin, copyout, create");
676 Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
708 "Parsed clause kind does not have a var-list");
722 "Modifier Kind only valid on copy, copyin, copyout, create");
723 Details = VarListDetails{std::move(VarList), ModKind};
729 "reduction details only valid on reduction");
730 Details = ReductionDetails{Op, std::move(VarList)};
736 "Parsed clause kind does not have a wait-details");
737 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
743 "Only 'device_type'/'dtype' has a device-type-arg list");
744 Details = DeviceTypeDetails{std::move(Archs)};
749 "Only 'collapse' has collapse details");
750 Details = CollapseDetails{IsForce, LoopCount};
754 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
757 "Only 'bind' has bind details");
758 Details = BindDetails{Arg};
772 const Stmt *RangeFor);
777 const Stmt *Second,
const Stmt *Third);
780 const Stmt *Second,
const Stmt *OldThird,
789 OpenACCParsedClause &Clause);
863 Decl *NextParsedDecl);
870 OpenACCRoutineDeclAttr *
871 mergeRoutineDeclAttr(
const OpenACCRoutineDeclAttr &Old);
895 void ActOnInvalidParseVar();
904 void ActOnVariableDeclarator(
VarDecl *VD);
928 bool CheckReductionVarType(
Expr *VarExpr);
979 LoopCheckingInfo OldLoopInfo;
980 CollapseCheckingInfo OldCollapseInfo;
981 TileCheckingInfo OldTileInfo;
986 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
987 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
988 PreserveDepth(PreserveDepth) {}
993 bool CollapseDepthSatisified =
994 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
995 : OldCollapseInfo.CollapseDepthSatisfied;
996 bool TileDepthSatisfied = PreserveDepth
997 ? SemaRef.TileInfo.TileDepthSatisfied
998 : OldTileInfo.TileDepthSatisfied;
999 bool CurLevelHasLoopAlready =
1000 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
1001 : OldLoopInfo.CurLevelHasLoopAlready;
1003 SemaRef.LoopInfo = OldLoopInfo;
1004 SemaRef.CollapseInfo = OldCollapseInfo;
1005 SemaRef.TileInfo = OldTileInfo;
1007 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
1008 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
1009 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
1018 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)
std::pair< FunctionDecl *, OpenACCRoutineDecl * > RoutineRefListTy
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.
The top declaration context.
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