//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file defines OpenMP AST classes for executable directives and /// clauses. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_STMTOPENMP_H #define LLVM_CLANG_AST_STMTOPENMP_H #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/SourceLocation.h" namespace clang { //===----------------------------------------------------------------------===// // AST classes for directives. //===----------------------------------------------------------------------===// /// Representation of an OpenMP canonical loop. /// /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form /// OpenMP 4.0, section 2.6 Canonical Loop Form /// OpenMP 4.5, section 2.6 Canonical Loop Form /// OpenMP 5.0, section 2.9.1 Canonical Loop Form /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form /// /// An OpenMP canonical loop is a for-statement or range-based for-statement /// with additional requirements that ensure that the number of iterations is /// known before entering the loop and allow skipping to an arbitrary iteration. /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is /// known to fulfill OpenMP's canonical loop requirements because of being /// associated to an OMPLoopBasedDirective. That is, the general structure is: /// /// OMPLoopBasedDirective /// [`- CapturedStmt ] /// [ `- CapturedDecl] /// ` OMPCanonicalLoop /// `- ForStmt/CXXForRangeStmt /// `- Stmt /// /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some /// directives such as OMPParallelForDirective, but others do not need them /// (such as OMPTileDirective). In The OMPCanonicalLoop and /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the /// directive. A OMPCanonicalLoop must not appear in the AST unless associated /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: /// /// [...] /// ` OMPCanonicalLoop /// `- ForStmt/CXXForRangeStmt /// `- CompoundStmt /// |- Leading in-between code (if any) /// |- OMPCanonicalLoop /// | `- ForStmt/CXXForRangeStmt /// | `- ... /// `- Trailing in-between code (if any) /// /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop /// to avoid confusion which loop belongs to the nesting. /// /// There are three different kinds of iteration variables for different /// purposes: /// * Loop user variable: The user-accessible variable with different value for /// each iteration. /// * Loop iteration variable: The variable used to identify a loop iteration; /// for range-based for-statement, this is the hidden iterator '__begin'. For /// other loops, it is identical to the loop user variable. Must be a /// random-access iterator, pointer or integer type. /// * Logical iteration counter: Normalized loop counter starting at 0 and /// incrementing by one at each iteration. Allows abstracting over the type /// of the loop iteration variable and is always an unsigned integer type /// appropriate to represent the range of the loop iteration variable. Its /// value corresponds to the logical iteration number in the OpenMP /// specification. /// /// This AST node provides two captured statements: /// * The distance function which computes the number of iterations. /// * The loop user variable function that computes the loop user variable when /// given a logical iteration number. /// /// These captured statements provide the link between C/C++ semantics and the /// logical iteration counters used by the OpenMPIRBuilder which is /// language-agnostic and therefore does not know e.g. how to advance a /// random-access iterator. The OpenMPIRBuilder will use this information to /// apply simd, workshare-loop, distribute, taskloop and loop directives to the /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an /// OMPLoopDirective and skipped when searching for the associated syntactical /// loop. /// /// Example: /// <code> /// std::vector<std::string> Container{1,2,3}; /// for (std::string Str : Container) /// Body(Str); /// </code> /// which is syntactic sugar for approximately: /// <code> /// auto &&__range = Container; /// auto __begin = std::begin(__range); /// auto __end = std::end(__range); /// for (; __begin != __end; ++__begin) { /// std::String Str = *__begin; /// Body(Str); /// } /// </code> /// In this example, the loop user variable is `Str`, the loop iteration /// variable is `__begin` of type `std::vector<std::string>::iterator` and the /// logical iteration number type is `size_t` (unsigned version of /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). /// Therefore, the distance function will be /// <code> /// [&](size_t &Result) { Result = __end - __begin; } /// </code> /// and the loop variable function is /// <code> /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { /// Result = __begin + Logical; /// } /// </code> /// The variable `__begin`, aka the loop iteration variable, is captured by /// value because it is modified in the loop body, but both functions require /// the initial value. The OpenMP specification explicitly leaves unspecified /// when the loop expressions are evaluated such that a capture by reference is /// sufficient. class OMPCanonicalLoop : public Stmt { … }; /// This is a basic class for representing single OpenMP executable /// directive. /// class OMPExecutableDirective : public Stmt { … }; /// This represents '#pragma omp parallel' directive. /// /// \code /// #pragma omp parallel private(a,b) reduction(+: c,d) /// \endcode /// In this example directive '#pragma omp parallel' has clauses 'private' /// with the variables 'a' and 'b' and 'reduction' with operator '+' and /// variables 'c' and 'd'. /// class OMPParallelDirective : public OMPExecutableDirective { … }; /// The base class for all loop-based directives, including loop transformation /// directives. class OMPLoopBasedDirective : public OMPExecutableDirective { … }; /// The base class for all loop transformation directives. class OMPLoopTransformationDirective : public OMPLoopBasedDirective { … }; /// This is a common base class for loop directives ('omp simd', 'omp /// for', 'omp for simd' etc.). It is responsible for the loop code generation. /// class OMPLoopDirective : public OMPLoopBasedDirective { … }; /// This represents '#pragma omp simd' directive. /// /// \code /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp simd' has clauses 'private' /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. /// class OMPSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp for' directive. /// /// \code /// #pragma omp for private(a,b) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp for' has clauses 'private' with the /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' /// and 'd'. /// class OMPForDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp for simd' directive. /// /// \code /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp for simd' has clauses 'private' /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. /// class OMPForSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp sections' directive. /// /// \code /// #pragma omp sections private(a,b) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp sections' has clauses 'private' with /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables /// 'c' and 'd'. /// class OMPSectionsDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp section' directive. /// /// \code /// #pragma omp section /// \endcode /// class OMPSectionDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp scope' directive. /// \code /// #pragma omp scope private(a,b) nowait /// \endcode /// In this example directive '#pragma omp scope' has clauses 'private' with /// the variables 'a' and 'b' and nowait. /// class OMPScopeDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp single' directive. /// /// \code /// #pragma omp single private(a,b) copyprivate(c,d) /// \endcode /// In this example directive '#pragma omp single' has clauses 'private' with /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. /// class OMPSingleDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp master' directive. /// /// \code /// #pragma omp master /// \endcode /// class OMPMasterDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp critical' directive. /// /// \code /// #pragma omp critical /// \endcode /// class OMPCriticalDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp parallel for' directive. /// /// \code /// #pragma omp parallel for private(a,b) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp parallel for' has clauses 'private' /// with the variables 'a' and 'b' and 'reduction' with operator '+' and /// variables 'c' and 'd'. /// class OMPParallelForDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel for simd' directive. /// /// \code /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp parallel for simd' has clauses /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' /// and linear step 's', 'reduction' with operator '+' and variables 'c' and /// 'd'. /// class OMPParallelForSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel master' directive. /// /// \code /// #pragma omp parallel master private(a,b) /// \endcode /// In this example directive '#pragma omp parallel master' has clauses /// 'private' with the variables 'a' and 'b' /// class OMPParallelMasterDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp parallel masked' directive. /// /// \code /// #pragma omp parallel masked filter(tid) /// \endcode /// In this example directive '#pragma omp parallel masked' has a clause /// 'filter' with the variable tid /// class OMPParallelMaskedDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp parallel sections' directive. /// /// \code /// #pragma omp parallel sections private(a,b) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp parallel sections' has clauses /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' /// and variables 'c' and 'd'. /// class OMPParallelSectionsDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp task' directive. /// /// \code /// #pragma omp task private(a,b) final(d) /// \endcode /// In this example directive '#pragma omp task' has clauses 'private' with the /// variables 'a' and 'b' and 'final' with condition 'd'. /// class OMPTaskDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp taskyield' directive. /// /// \code /// #pragma omp taskyield /// \endcode /// class OMPTaskyieldDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp barrier' directive. /// /// \code /// #pragma omp barrier /// \endcode /// class OMPBarrierDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp taskwait' directive. /// /// \code /// #pragma omp taskwait /// \endcode /// class OMPTaskwaitDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp taskgroup' directive. /// /// \code /// #pragma omp taskgroup /// \endcode /// class OMPTaskgroupDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp flush' directive. /// /// \code /// #pragma omp flush(a,b) /// \endcode /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' /// and 'b'. /// 'omp flush' directive does not have clauses but have an optional list of /// variables to flush. This list of variables is stored within some fake clause /// FlushClause. class OMPFlushDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp depobj' directive. /// /// \code /// #pragma omp depobj(a) depend(in:x,y) /// \endcode /// In this example directive '#pragma omp depobj' initializes a depobj object /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. class OMPDepobjDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp ordered' directive. /// /// \code /// #pragma omp ordered /// \endcode /// class OMPOrderedDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp atomic' directive. /// /// \code /// #pragma omp atomic capture /// \endcode /// In this example directive '#pragma omp atomic' has clause 'capture'. /// class OMPAtomicDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target' directive. /// /// \code /// #pragma omp target if(a) /// \endcode /// In this example directive '#pragma omp target' has clause 'if' with /// condition 'a'. /// class OMPTargetDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target data' directive. /// /// \code /// #pragma omp target data device(0) if(a) map(b[:]) /// \endcode /// In this example directive '#pragma omp target data' has clauses 'device' /// with the value '0', 'if' with condition 'a' and 'map' with array /// section 'b[:]'. /// class OMPTargetDataDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target enter data' directive. /// /// \code /// #pragma omp target enter data device(0) if(a) map(b[:]) /// \endcode /// In this example directive '#pragma omp target enter data' has clauses /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array /// section 'b[:]'. /// class OMPTargetEnterDataDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target exit data' directive. /// /// \code /// #pragma omp target exit data device(0) if(a) map(b[:]) /// \endcode /// In this example directive '#pragma omp target exit data' has clauses /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array /// section 'b[:]'. /// class OMPTargetExitDataDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target parallel' directive. /// /// \code /// #pragma omp target parallel if(a) /// \endcode /// In this example directive '#pragma omp target parallel' has clause 'if' with /// condition 'a'. /// class OMPTargetParallelDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp target parallel for' directive. /// /// \code /// #pragma omp target parallel for private(a,b) reduction(+:c,d) /// \endcode /// In this example directive '#pragma omp target parallel for' has clauses /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' /// and variables 'c' and 'd'. /// class OMPTargetParallelForDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp teams' directive. /// /// \code /// #pragma omp teams if(a) /// \endcode /// In this example directive '#pragma omp teams' has clause 'if' with /// condition 'a'. /// class OMPTeamsDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp cancellation point' directive. /// /// \code /// #pragma omp cancellation point for /// \endcode /// /// In this example a cancellation point is created for innermost 'for' region. class OMPCancellationPointDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp cancel' directive. /// /// \code /// #pragma omp cancel for /// \endcode /// /// In this example a cancel is created for innermost 'for' region. class OMPCancelDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp taskloop' directive. /// /// \code /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp taskloop' has clauses 'private' /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and /// 'num_tasks' with expression 'num'. /// class OMPTaskLoopDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp taskloop simd' directive. /// /// \code /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp taskloop simd' has clauses 'private' /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and /// 'num_tasks' with expression 'num'. /// class OMPTaskLoopSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp master taskloop' directive. /// /// \code /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp master taskloop' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPMasterTaskLoopDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp masked taskloop' directive. /// /// \code /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp masked taskloop' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp master taskloop simd' directive. /// /// \code /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp master taskloop simd' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp masked taskloop simd' directive. /// /// \code /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) /// \endcode /// In this example directive '#pragma omp masked taskloop simd' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel master taskloop' directive. /// /// \code /// #pragma omp parallel master taskloop private(a,b) grainsize(val) /// num_tasks(num) /// \endcode /// In this example directive '#pragma omp parallel master taskloop' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel masked taskloop' directive. /// /// \code /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) /// num_tasks(num) /// \endcode /// In this example directive '#pragma omp parallel masked taskloop' has clauses /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' /// and 'num_tasks' with expression 'num'. /// class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel master taskloop simd' directive. /// /// \code /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) /// num_tasks(num) /// \endcode /// In this example directive '#pragma omp parallel master taskloop simd' has /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with /// expression 'val' and 'num_tasks' with expression 'num'. /// class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel masked taskloop simd' directive. /// /// \code /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) /// num_tasks(num) /// \endcode /// In this example directive '#pragma omp parallel masked taskloop simd' has /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with /// expression 'val' and 'num_tasks' with expression 'num'. /// class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp distribute' directive. /// /// \code /// #pragma omp distribute private(a,b) /// \endcode /// In this example directive '#pragma omp distribute' has clauses 'private' /// with the variables 'a' and 'b' /// class OMPDistributeDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp target update' directive. /// /// \code /// #pragma omp target update to(a) from(b) device(1) /// \endcode /// In this example directive '#pragma omp target update' has clause 'to' with /// argument 'a', clause 'from' with argument 'b' and clause 'device' with /// argument '1'. /// class OMPTargetUpdateDirective : public OMPExecutableDirective { … }; /// This represents '#pragma omp distribute parallel for' composite /// directive. /// /// \code /// #pragma omp distribute parallel for private(a,b) /// \endcode /// In this example directive '#pragma omp distribute parallel for' has clause /// 'private' with the variables 'a' and 'b' /// class OMPDistributeParallelForDirective : public OMPLoopDirective { … }; /// This represents '#pragma omp distribute parallel for simd' composite /// directive. /// /// \code /// #pragma omp distribute parallel for simd private(x) /// \endcode /// In this example directive '#pragma omp distribute parallel for simd' has /// clause 'private' with the variables 'x' /// class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp distribute simd' composite directive. /// /// \code /// #pragma omp distribute simd private(x) /// \endcode /// In this example directive '#pragma omp distribute simd' has clause /// 'private' with the variables 'x' /// class OMPDistributeSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target parallel for simd' directive. /// /// \code /// #pragma omp target parallel for simd private(a) map(b) safelen(c) /// \endcode /// In this example directive '#pragma omp target parallel for simd' has clauses /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' /// with the variable 'c'. /// class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target simd' directive. /// /// \code /// #pragma omp target simd private(a) map(b) safelen(c) /// \endcode /// In this example directive '#pragma omp target simd' has clauses 'private' /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with /// the variable 'c'. /// class OMPTargetSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp teams distribute' directive. /// /// \code /// #pragma omp teams distribute private(a,b) /// \endcode /// In this example directive '#pragma omp teams distribute' has clauses /// 'private' with the variables 'a' and 'b' /// class OMPTeamsDistributeDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp teams distribute simd' /// combined directive. /// /// \code /// #pragma omp teams distribute simd private(a,b) /// \endcode /// In this example directive '#pragma omp teams distribute simd' /// has clause 'private' with the variables 'a' and 'b' /// class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp teams distribute parallel for simd' composite /// directive. /// /// \code /// #pragma omp teams distribute parallel for simd private(x) /// \endcode /// In this example directive '#pragma omp teams distribute parallel for simd' /// has clause 'private' with the variables 'x' /// class OMPTeamsDistributeParallelForSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp teams distribute parallel for' composite /// directive. /// /// \code /// #pragma omp teams distribute parallel for private(x) /// \endcode /// In this example directive '#pragma omp teams distribute parallel for' /// has clause 'private' with the variables 'x' /// class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target teams' directive. /// /// \code /// #pragma omp target teams if(a>0) /// \endcode /// In this example directive '#pragma omp target teams' has clause 'if' with /// condition 'a>0'. /// class OMPTargetTeamsDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp target teams distribute' combined directive. /// /// \code /// #pragma omp target teams distribute private(x) /// \endcode /// In this example directive '#pragma omp target teams distribute' has clause /// 'private' with the variables 'x' /// class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target teams distribute parallel for' combined /// directive. /// /// \code /// #pragma omp target teams distribute parallel for private(x) /// \endcode /// In this example directive '#pragma omp target teams distribute parallel /// for' has clause 'private' with the variables 'x' /// class OMPTargetTeamsDistributeParallelForDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target teams distribute parallel for simd' /// combined directive. /// /// \code /// #pragma omp target teams distribute parallel for simd private(x) /// \endcode /// In this example directive '#pragma omp target teams distribute parallel /// for simd' has clause 'private' with the variables 'x' /// class OMPTargetTeamsDistributeParallelForSimdDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target teams distribute simd' combined /// directive. /// /// \code /// #pragma omp target teams distribute simd private(x) /// \endcode /// In this example directive '#pragma omp target teams distribute simd' /// has clause 'private' with the variables 'x' /// class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { … }; /// This represents the '#pragma omp tile' loop transformation directive. class OMPTileDirective final : public OMPLoopTransformationDirective { … }; /// This represents the '#pragma omp unroll' loop transformation directive. /// /// \code /// #pragma omp unroll /// for (int i = 0; i < 64; ++i) /// \endcode class OMPUnrollDirective final : public OMPLoopTransformationDirective { … }; /// Represents the '#pragma omp reverse' loop transformation directive. /// /// \code /// #pragma omp reverse /// for (int i = 0; i < n; ++i) /// ... /// \endcode class OMPReverseDirective final : public OMPLoopTransformationDirective { … }; /// Represents the '#pragma omp interchange' loop transformation directive. /// /// \code{c} /// #pragma omp interchange /// for (int i = 0; i < m; ++i) /// for (int j = 0; j < n; ++j) /// .. /// \endcode class OMPInterchangeDirective final : public OMPLoopTransformationDirective { … }; /// This represents '#pragma omp scan' directive. /// /// \code /// #pragma omp scan inclusive(a) /// \endcode /// In this example directive '#pragma omp scan' has clause 'inclusive' with /// list item 'a'. class OMPScanDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp interop' directive. /// /// \code /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait /// \endcode /// In this example directive '#pragma omp interop' has /// clauses 'init', 'device', 'depend' and 'nowait'. /// class OMPInteropDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp dispatch' directive. /// /// \code /// #pragma omp dispatch device(dnum) /// \endcode /// This example shows a directive '#pragma omp dispatch' with a /// device clause with variable 'dnum'. /// class OMPDispatchDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp masked' directive. /// \code /// #pragma omp masked filter(tid) /// \endcode /// This example shows a directive '#pragma omp masked' with a filter clause /// with variable 'tid'. /// class OMPMaskedDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp metadirective' directive. /// /// \code /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) /// \endcode /// In this example directive '#pragma omp metadirective' has clauses 'when' /// with a dynamic user condition to check if a variable 'N > 10' /// class OMPMetaDirective final : public OMPExecutableDirective { … }; /// This represents '#pragma omp loop' directive. /// /// \code /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) /// \endcode /// In this example directive '#pragma omp loop' has /// clauses 'private' with the variables 'a' and 'b', 'binding' with /// modifier 'parallel' and 'order(concurrent). /// class OMPGenericLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp teams loop' directive. /// /// \code /// #pragma omp teams loop private(a,b) order(concurrent) /// \endcode /// In this example directive '#pragma omp teams loop' has /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). /// class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target teams loop' directive. /// /// \code /// #pragma omp target teams loop private(a,b) order(concurrent) /// \endcode /// In this example directive '#pragma omp target teams loop' has /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). /// class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp parallel loop' directive. /// /// \code /// #pragma omp parallel loop private(a,b) order(concurrent) /// \endcode /// In this example directive '#pragma omp parallel loop' has /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). /// class OMPParallelGenericLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp target parallel loop' directive. /// /// \code /// #pragma omp target parallel loop private(a,b) order(concurrent) /// \endcode /// In this example directive '#pragma omp target parallel loop' has /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). /// class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { … }; /// This represents '#pragma omp error' directive. /// /// \code /// #pragma omp error /// \endcode class OMPErrorDirective final : public OMPExecutableDirective { … }; // It's not really an executable directive, but it seems convenient to use // that as the parent class. class OMPAssumeDirective final : public OMPExecutableDirective { … }; } // end namespace clang #endif