*/
CXCursor_OMPForSimdDirective = 250,
- CXCursor_LastStmt = CXCursor_OMPForSimdDirective,
+ /** \brief OpenMP target directive.
+ */
+ CXCursor_OMPTargetDirective = 251,
+
+ CXCursor_LastStmt = CXCursor_OMPTargetDirective,
/**
* \brief Cursor that represents the translation unit itself.
DEF_TRAVERSE_STMT(OMPAtomicDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
DEF_TRAVERSE_STMT(OMPAtomicDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
}
};
+/// \brief 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 {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ StartLoc, EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTargetDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
#ifndef OPENMP_ATOMIC_CLAUSE
# define OPENMP_ATOMIC_CLAUSE(Name)
#endif
+#ifndef OPENMP_TARGET_CLAUSE
+# define OPENMP_TARGET_CLAUSE(Name)
+#endif
#ifndef OPENMP_DEFAULT_KIND
# define OPENMP_DEFAULT_KIND(Name)
#endif
OPENMP_DIRECTIVE(flush)
OPENMP_DIRECTIVE(ordered)
OPENMP_DIRECTIVE(atomic)
+OPENMP_DIRECTIVE(target)
OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
OPENMP_ATOMIC_CLAUSE(capture)
OPENMP_ATOMIC_CLAUSE(seq_cst)
+// Clauses allowed for OpenMP directive 'target'.
+// TODO More clauses for 'target' directive.
+OPENMP_TARGET_CLAUSE(if)
+
#undef OPENMP_SCHEDULE_KIND
#undef OPENMP_PROC_BIND_KIND
#undef OPENMP_DEFAULT_KIND
#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
#undef OPENMP_TASK_CLAUSE
#undef OPENMP_ATOMIC_CLAUSE
+#undef OPENMP_TARGET_CLAUSE
#undef OPENMP_SIMD_CLAUSE
#undef OPENMP_FOR_CLAUSE
#undef OPENMP_FOR_SIMD_CLAUSE
def OMPFlushDirective : DStmt<OMPExecutableDirective>;
def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetDirective : DStmt<OMPExecutableDirective>;
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp target' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
Expr *Expr,
SourceLocation StartLoc,
STMT_OMP_FLUSH_DIRECTIVE,
STMT_OMP_ORDERED_DIRECTIVE,
STMT_OMP_ATOMIC_DIRECTIVE,
+ STMT_OMP_TARGET_DIRECTIVE,
// ARC
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
return new (Mem) OMPAtomicDirective(NumClauses);
}
+OMPTargetDirective *OMPTargetDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPTargetDirective *Dir =
+ new (Mem) OMPTargetDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPTargetDirective *OMPTargetDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPTargetDirective(NumClauses);
+}
+
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
+ Indent() << "#pragma omp target ";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
#define OPENMP_ATOMIC_CLAUSE(Name) \
case OMPC_##Name: \
return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_target:
+ switch (CKind) {
+#define OPENMP_TARGET_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
case Stmt::OMPAtomicDirectiveClass:
EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));
break;
+ case Stmt::OMPTargetDirectiveClass:
+ EmitOMPTargetDirective(cast<OMPTargetDirective>(*S));
+ break;
}
}
llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
}
+void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
+ llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
+}
+
void EmitOMPFlushDirective(const OMPFlushDirective &S);
void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
+ void EmitOMPTargetDirective(const OMPTargetDirective &S);
//===--------------------------------------------------------------------===//
// LValue Expression Emission
case OMPD_parallel_for:
case OMPD_parallel_sections:
case OMPD_atomic:
+ case OMPD_target:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
break;
/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
-/// 'for simd' {clause}
+/// 'for simd' | 'target' {clause}
/// annot_pragma_openmp_end
///
StmtResult
case OMPD_parallel_sections:
case OMPD_task:
case OMPD_ordered:
- case OMPD_atomic: {
+ case OMPD_atomic:
+ case OMPD_target: {
ConsumeToken();
// Parse directive name of the 'critical' directive if any.
if (DKind == OMPD_critical) {
Params);
break;
}
+ case OMPD_target: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
case OMPD_threadprivate:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
// | parallel | flush | * |
// | parallel | ordered | + |
// | parallel | atomic | * |
+ // | parallel | target | * |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
// | for | flush | * |
// | for | ordered | * (if construct is ordered) |
// | for | atomic | * |
+ // | for | target | * |
// +------------------+-----------------+------------------------------------+
// | master | parallel | * |
// | master | for | + |
// | master | flush | * |
// | master | ordered | + |
// | master | atomic | * |
+ // | master | target | * |
// +------------------+-----------------+------------------------------------+
// | critical | parallel | * |
// | critical | for | + |
// | critical | taskwait | * |
// | critical | ordered | + |
// | critical | atomic | * |
+ // | critical | target | * |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
// | simd | flush | |
// | simd | ordered | |
// | simd | atomic | |
+ // | simd | target | |
// +------------------+-----------------+------------------------------------+
// | for simd | parallel | |
// | for simd | for | |
// | for simd | flush | |
// | for simd | ordered | |
// | for simd | atomic | |
+ // | for simd | target | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
// | sections | flush | * |
// | sections | ordered | + |
// | sections | atomic | * |
+ // | sections | target | * |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
// | section | flush | * |
// | section | ordered | + |
// | section | atomic | * |
+ // | section | target | * |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
// | single | flush | * |
// | single | ordered | + |
// | single | atomic | * |
+ // | single | target | * |
// +------------------+-----------------+------------------------------------+
// | parallel for | parallel | * |
// | parallel for | for | + |
// | parallel for | flush | * |
// | parallel for | ordered | * (if construct is ordered) |
// | parallel for | atomic | * |
+ // | parallel for | target | * |
// +------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * |
// | parallel sections| for | + |
// | parallel sections| flush | * |
// | parallel sections| ordered | + |
// | parallel sections| atomic | * |
+ // | parallel sections| target | * |
// +------------------+-----------------+------------------------------------+
// | task | parallel | * |
// | task | for | + |
// | task | flush | * |
// | task | ordered | + |
// | task | atomic | * |
+ // | task | target | * |
// +------------------+-----------------+------------------------------------+
// | ordered | parallel | * |
// | ordered | for | + |
// | ordered | flush | * |
// | ordered | ordered | + |
// | ordered | atomic | * |
+ // | ordered | target | * |
+ // +------------------+-----------------+------------------------------------+
+ // | atomic | parallel | |
+ // | atomic | for | |
+ // | atomic | for simd | |
+ // | atomic | master | |
+ // | atomic | critical | |
+ // | atomic | simd | |
+ // | atomic | sections | |
+ // | atomic | section | |
+ // | atomic | single | |
+ // | atomic | parallel for | |
+ // | atomic |parallel sections| |
+ // | atomic | task | |
+ // | atomic | taskyield | |
+ // | atomic | barrier | |
+ // | atomic | taskwait | |
+ // | atomic | flush | |
+ // | atomic | ordered | |
+ // | atomic | atomic | |
+ // | atomic | target | |
+ // +------------------+-----------------+------------------------------------+
+ // | target | parallel | * |
+ // | target | for | * |
+ // | target | for simd | * |
+ // | target | master | * |
+ // | target | critical | * |
+ // | target | simd | * |
+ // | target | sections | * |
+ // | target | section | * |
+ // | target | single | * |
+ // | target | parallel for | * |
+ // | target |parallel sections| * |
+ // | target | task | * |
+ // | target | taskyield | * |
+ // | target | barrier | * |
+ // | target | taskwait | * |
+ // | target | flush | * |
+ // | target | ordered | * |
+ // | target | atomic | * |
+ // | target | target | * |
// +------------------+-----------------+------------------------------------+
if (Stack->getCurScope()) {
auto ParentRegion = Stack->getParentDirective();
Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
EndLoc);
break;
+ case OMPD_target:
+ Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc);
+ break;
case OMPD_threadprivate:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
}
+StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+ getCurFunction()->setHasBranchProtectedScope();
+
+ return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
return Res;
}
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clause transformation
//===----------------------------------------------------------------------===//
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPTargetDirective(OMPTargetDirective *D) {
+ VisitStmt(D);
+ // The NumClauses field was read in ReadStmtFromStream.
+ ++Idx;
+ VisitOMPExecutableDirective(D);
+}
+
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
+ case STMT_OMP_TARGET_DIRECTIVE:
+ S = OMPTargetDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
+ break;
+
case EXPR_CXX_OPERATOR_CALL:
S = new (Context) CXXOperatorCallExpr(Context, Empty);
break;
Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
+ VisitStmt(D);
+ Record.push_back(D->getNumClauses());
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
case Stmt::OMPFlushDirectiveClass:
case Stmt::OMPOrderedDirectiveClass:
case Stmt::OMPAtomicDirectiveClass:
+ case Stmt::OMPTargetDirectiveClass:
llvm_unreachable("Stmt should not be in analyzer evaluation loop");
case Stmt::ObjCSubscriptRefExprClass:
#pragma omp atomic
++a;
}
+#pragma omp parallel
+ {
+#pragma omp target
+ ++a;
+ }
// SIMD DIRECTIVE
#pragma omp simd
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
// FOR DIRECTIVE
#pragma omp for
#pragma omp atomic
++a;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target
+ ++a;
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
#pragma omp atomic
++a;
}
+#pragma omp sections
+ {
+#pragma omp target
+ ++a;
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
#pragma omp atomic
++a;
}
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp target
+ ++a;
+ }
// SINGLE DIRECTIVE
#pragma omp single
#pragma omp atomic
++a;
}
+#pragma omp single
+ {
+#pragma omp target
+ ++a;
+ }
// MASTER DIRECTIVE
#pragma omp master
#pragma omp atomic
++a;
}
+#pragma omp master
+ {
+#pragma omp target
+ ++a;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
#pragma omp atomic
++a;
}
+#pragma omp critical
+ {
+#pragma omp target
+ ++a;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
#pragma omp atomic
++a;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target
+ ++a;
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
#pragma omp atomic
++a;
}
+#pragma omp parallel sections
+ {
+#pragma omp target
+ ++a;
+ }
// TASK DIRECTIVE
#pragma omp task
#pragma omp atomic
++a;
}
+#pragma omp task
+ {
+#pragma omp target
+ ++a;
+ }
// ORDERED DIRECTIVE
#pragma omp ordered
#pragma omp atomic
++a;
}
+#pragma omp ordered
+ {
+#pragma omp target
+ ++a;
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
+#pragma omp atomic
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+
+// TARGET DIRECTIVE
+#pragma omp target
+#pragma omp parallel
+ bar();
+#pragma omp target
+#pragma omp for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp sections
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}}
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp single
+ bar();
+
+#pragma omp target
+#pragma omp master
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp critical
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp parallel sections
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp task
+ {
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp barrier
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target
+ {
+#pragma omp target
+ ++a;
+ }
}
void foo() {
#pragma omp atomic
++a;
}
+#pragma omp parallel
+ {
+#pragma omp target
+ ++a;
+ }
// SIMD DIRECTIVE
#pragma omp simd
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
// FOR DIRECTIVE
#pragma omp for
#pragma omp atomic
++a;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target
+ ++a;
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
#pragma omp atomic
++a;
}
+#pragma omp sections
+ {
+#pragma omp target
+ ++a;
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
++a;
}
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target
+ ++a;
+ }
+ }
// SINGLE DIRECTIVE
#pragma omp single
#pragma omp atomic
++a;
}
+#pragma omp single
+ {
+#pragma omp target
+ ++a;
+ }
// MASTER DIRECTIVE
#pragma omp master
#pragma omp atomic
++a;
}
+#pragma omp master
+ {
+#pragma omp target
+ ++a;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
#pragma omp atomic
++a;
}
+#pragma omp critical
+ {
+#pragma omp target
+ ++a;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
#pragma omp atomic
++a;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target
+ ++a;
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
#pragma omp atomic
++a;
}
+#pragma omp parallel sections
+ {
+#pragma omp target
+ ++a;
+ }
// TASK DIRECTIVE
#pragma omp task
#pragma omp atomic
++a;
}
+#pragma omp task
+ {
+#pragma omp target
+ ++a;
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
for (int i = 0; i < 10; ++i)
;
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
{
}
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
bar();
}
#pragma omp atomic
-// expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
{
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
+#pragma omp atomic
+ // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+
+// TARGET DIRECTIVE
+#pragma omp target
+#pragma omp parallel
+ bar();
+#pragma omp target
+#pragma omp for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp sections
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}}
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp single
+ bar();
+
+#pragma omp target
+#pragma omp master
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp critical
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp parallel sections
+ {
+ bar();
+ }
+#pragma omp target
+#pragma omp task
+ {
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp barrier
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target
+ {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target
+ {
+#pragma omp target
+ ++a;
+ }
return foo<int>();
}
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+#pragma omp target
+ foo();
+#pragma omp target if (argc > 0)
+ foo();
+#pragma omp target if (C)
+ foo();
+ return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target if(argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target if(5)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target if(argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target if(1)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target if(argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target if(C)
+// CHECK-NEXT: foo()
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main (int argc, char **argv) {
+#pragma omp target
+// CHECK-NEXT: #pragma omp target
+ foo();
+// CHECK-NEXT: foo();
+#pragma omp target if (argc > 0)
+// CHECK-NEXT: #pragma omp target if(argc > 0)
+ foo();
+// CHECK-NEXT: foo();
+ return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
+}
+
+#endif
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ #pragma omp target if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if () // expected-error {{expected expression}}
+ #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ #pragma omp target if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}}
+ #pragma omp target if (S) // expected-error {{'S' does not refer to a value}}
+ #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if(argc)
+ foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if () // expected-error {{expected expression}}
+ #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ #pragma omp target if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}}
+ #pragma omp target if (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+
+ return tmain(argc, argv);
+}
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp target // expected-error {{unexpected OpenMP directive '#pragma omp target'}}
+
+int main(int argc, char **argv) {
+ #pragma omp target { // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target ( // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target [ // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target ] // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target ) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target } // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target
+ // expected-warning@+1 {{extra tokens at the end of '#pragma omp target' are ignored}}
+ #pragma omp target unknown()
+ foo();
+ L1:
+ foo();
+ #pragma omp target
+ ;
+ #pragma omp target
+ {
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ argc++;
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ switch(argc) {
+ case (0):
+ #pragma omp target
+ {
+ foo();
+ break; // expected-error {{'break' statement not in loop or switch statement}}
+ continue; // expected-error {{'continue' statement not in loop statement}}
+ }
+ default:
+ break;
+ }
+ }
+
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ #pragma omp target
+ L2:
+ foo();
+ #pragma omp target
+ {
+ return 1; // expected-error {{cannot return from OpenMP region}}
+ }
+
+ [[]] // expected-error {{an attribute list cannot appear here}}
+ #pragma omp target
+ for (int n = 0; n < 100; ++n) {}
+
+ return 0;
+}
+
void VisitOMPFlushDirective(const OMPFlushDirective *D);
void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
+ void VisitOMPTargetDirective(const OMPTargetDirective *D);
private:
void AddDeclarationNameInfo(const Stmt *S);
VisitOMPExecutableDirective(D);
}
+void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
return cxstring::createRef("OMPOrderedDirective");
case CXCursor_OMPAtomicDirective:
return cxstring::createRef("OMPAtomicDirective");
+ case CXCursor_OMPTargetDirective:
+ return cxstring::createRef("OMPTargetDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
case Stmt::OMPAtomicDirectiveClass:
K = CXCursor_OMPAtomicDirective;
break;
+ case Stmt::OMPTargetDirectiveClass:
+ K = CXCursor_OMPTargetDirective;
+ break;
}
CXCursor C = { K, 0, { Parent, S, TU } };