*/
CXCursor_OMPTaskLoopSimdDirective = 259,
- /** \brief OpenMP distribute directive.
+ /** \brief OpenMP distribute directive.
*/
CXCursor_OMPDistributeDirective = 260,
*/
CXCursor_OMPTargetParallelForDirective = 264,
- CXCursor_LastStmt = CXCursor_OMPTargetParallelForDirective,
+ /** \brief OpenMP target update directive.
+ */
+ CXCursor_OMPTargetUpdateDirective = 265,
+
+ CXCursor_LastStmt = CXCursor_OMPTargetUpdateDirective,
/**
* \brief Cursor that represents the translation unit itself.
DEF_TRAVERSE_STMT(OMPTeamsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
- ///
+ ///
static OMPDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
}
};
+/// \brief 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 {
+ 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 The number of clauses.
+ ///
+ OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
+ OMPD_target_update, StartLoc, EndLoc, NumClauses,
+ 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetUpdateDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
+ OMPD_target_update, SourceLocation(),
+ SourceLocation(), NumClauses, 0) {}
+
+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.
+ ///
+ static OMPTargetUpdateDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses The number of clauses.
+ ///
+ static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
"expected a reference to a parameter specified in a 'uniform' clause">;
def err_omp_expected_int_param : Error<
"expected a reference to an integer-typed parameter">;
+def err_omp_at_least_one_motion_clause_required : Error<
+ "expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
#ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE
# define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name)
#endif
+#ifndef OPENMP_TARGET_UPDATE_CLAUSE
+# define OPENMP_TARGET_UPDATE_CLAUSE(Name)
+#endif
#ifndef OPENMP_TEAMS_CLAUSE
# define OPENMP_TEAMS_CLAUSE(Name)
#endif
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
OPENMP_DIRECTIVE_EXT(target_parallel, "target parallel")
OPENMP_DIRECTIVE_EXT(target_parallel_for, "target parallel for")
+OPENMP_DIRECTIVE_EXT(target_update, "target update")
OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear)
+// Clauses allowed for OpenMP directive 'target update'.
+// TODO More clauses for 'target update' directive.
+OPENMP_TARGET_UPDATE_CLAUSE(if)
+OPENMP_TARGET_UPDATE_CLAUSE(device)
+
// Clauses allowed for OpenMP directive 'teams'.
// TODO More clauses for 'teams' directive.
OPENMP_TEAMS_CLAUSE(default)
#undef OPENMP_DIST_SCHEDULE_KIND
#undef OPENMP_DEFAULTMAP_KIND
#undef OPENMP_DEFAULTMAP_MODIFIER
+#undef OPENMP_TARGET_UPDATE_CLAUSE
def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>;
def OMPTargetParallelDirective : DStmt<OMPExecutableDirective>;
def OMPTargetParallelForDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetUpdateDirective : DStmt<OMPExecutableDirective>;
def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>;
def OMPCancelDirective : DStmt<OMPExecutableDirective>;
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// \brief Called on well-formed '\#pragma omp target update'.
+ StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Checks correctness of linear modifiers.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
STMT_OMP_TASKLOOP_DIRECTIVE,
STMT_OMP_TASKLOOP_SIMD_DIRECTIVE,
STMT_OMP_DISTRIBUTE_DIRECTIVE,
+ STMT_OMP_TARGET_UPDATE_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
// ARC
numLoopChildren(CollapsedNum, OMPD_distribute));
return new (Mem) OMPDistributeDirective(CollapsedNum, NumClauses);
}
+
+OMPTargetUpdateDirective *
+OMPTargetUpdateDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses) {
+ unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
+ OMPTargetUpdateDirective *Dir =
+ new (Mem) OMPTargetUpdateDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ return Dir;
+}
+
+OMPTargetUpdateDirective *
+OMPTargetUpdateDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
+ return new (Mem) OMPTargetUpdateDirective(NumClauses);
+}
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTargetUpdateDirective(
+ OMPTargetUpdateDirective *Node) {
+ Indent() << "#pragma omp target update ";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
+void StmtProfiler::VisitOMPTargetUpdateDirective(
+ const OMPTargetUpdateDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \
case OMPC_##Name: \
return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_target_update:
+ switch (CKind) {
+#define OPENMP_TARGET_UPDATE_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
// TODO add target update directive check.
return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
- DKind == OMPD_target_exit_data;
+ DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
}
bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
case Stmt::OMPDistributeDirectiveClass:
EmitOMPDistributeDirective(cast<OMPDistributeDirective>(*S));
break;
+ case Stmt::OMPTargetUpdateDirectiveClass:
+ EmitOMPTargetUpdateDirective(cast<OMPTargetUpdateDirective>(*S));
+ break;
}
}
const OMPTaskLoopSimdDirective &S) {
EmitOMPTaskLoopBasedDirective(S);
}
+
+// Generate the instructions for '#pragma omp target update' directive.
+void CodeGenFunction::EmitOMPTargetUpdateDirective(
+ const OMPTargetUpdateDirective &S) {
+ // TODO: codegen for target update
+}
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S);
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
+ void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S);
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S);
void
EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S);
OMPD_point,
OMPD_reduction,
OMPD_target_enter,
- OMPD_target_exit
+ OMPD_target_exit,
+ OMPD_update,
};
class ThreadprivateListParserHelper final {
.Case("exit", OMPD_exit)
.Case("point", OMPD_point)
.Case("reduction", OMPD_reduction)
+ .Case("update", OMPD_update)
.Default(OMPD_unknown);
}
{ OMPD_target, OMPD_data, OMPD_target_data },
{ OMPD_target, OMPD_enter, OMPD_target_enter },
{ OMPD_target, OMPD_exit, OMPD_target_exit },
+ { OMPD_target, OMPD_update, OMPD_target_update },
{ OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
{ OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
{ OMPD_for, OMPD_simd, OMPD_for_simd },
case OMPD_taskloop_simd:
case OMPD_distribute:
case OMPD_end_declare_target:
+ case OMPD_target_update:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
break;
/// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
/// 'distribute' | 'target enter data' | 'target exit data' |
-/// 'target parallel' | 'target parallel for' {clause}
+/// 'target parallel' | 'target parallel for' |
+/// 'target update' {clause}
/// annot_pragma_openmp_end
///
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_cancel:
case OMPD_target_enter_data:
case OMPD_target_exit_data:
+ case OMPD_target_update:
if (Allowed == ACK_StatementsOpenMPNonStandalone) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
+ case OMPD_target_update:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
EndLoc, VarsWithInheritedDSA);
break;
+ case OMPD_target_update:
+ assert(!AStmt && "Statement is not allowed for target update");
+ Res =
+ ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc);
+ AllowedNameModifiers.push_back(OMPD_target_update);
+ break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_threadprivate:
return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses);
}
+StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ // TODO: Set this flag accordingly when we add support for the 'to' and 'from'
+ // clauses.
+ bool seenMotionClause = false;
+
+ if (!seenMotionClause) {
+ Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
+ return StmtError();
+ }
+ return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses);
+}
+
StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc) {
// Save the components and declaration to create the clause. For purposes of
// the clause creation, any component list that has has base 'this' uses
- // null has
+ // null as base declaration.
ClauseComponents.resize(ClauseComponents.size() + 1);
ClauseComponents.back().append(CurComponents.begin(), CurComponents.end());
ClauseBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
return Res;
}
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
+ OMPTargetUpdateDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
+ nullptr, D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
VisitOMPLoopDirective(D);
}
+void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
+ VisitStmt(D);
+ ++Idx;
+ VisitOMPExecutableDirective(D);
+}
+
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
break;
}
+ case STMT_OMP_TARGET_UPDATE_DIRECTIVE:
+ S = OMPTargetUpdateDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
+ break;
+
case STMT_OMP_TEAMS_DIRECTIVE:
S = OMPTeamsDirective::CreateEmpty(
Context, Record[ASTStmtReader::NumStmtFields], Empty);
Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
+ VisitStmt(D);
+ Record.push_back(D->getNumClauses());
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
+}
+
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
case Stmt::OMPTargetExitDataDirectiveClass:
case Stmt::OMPTargetParallelDirectiveClass:
case Stmt::OMPTargetParallelForDirectiveClass:
+ case Stmt::OMPTargetUpdateDirectiveClass:
case Stmt::OMPTeamsDirectiveClass:
case Stmt::OMPCancellationPointDirectiveClass:
case Stmt::OMPCancelDirectiveClass:
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// SIMD DIRECTIVE
#pragma omp simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ }
// FOR DIRECTIVE
#pragma omp for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+ bar();
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
+ }
// SINGLE DIRECTIVE
#pragma omp single
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp single
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
// MASTER DIRECTIVE
#pragma omp master
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp master
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp critical
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// PARALLEL FOR SIMD DIRECTIVE
#pragma omp parallel for simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel sections
+ {
+#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// TASK DIRECTIVE
#pragma omp task
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp task
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
// ORDERED DIRECTIVE
#pragma omp ordered
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp ordered
+ {
+ bar();
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{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-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ bar();
+ }
// TARGET DIRECTIVE
#pragma omp target
{
#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
}
+#pragma omp target
+ {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
+ }
// TARGET PARALLEL DIRECTIVE
#pragma omp target parallel
{
#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
}
+#pragma omp target parallel
+ {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
// TARGET PARALLEL FOR DIRECTIVE
#pragma omp target parallel for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ }
// TEAMS DIRECTIVE
#pragma omp target
#pragma omp distribute
for (int j = 0; j < 10; ++j)
;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+ }
// TASKLOOP DIRECTIVE
#pragma omp taskloop
for (int i = 0; i < 10; ++i)
++a;
}
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ bar();
+ }
+
+
// DISTRIBUTE DIRECTIVE
#pragma omp target
#pragma omp teams
#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
}
void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
// SIMD DIRECTIVE
#pragma omp simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ a++;
+ }
// FOR DIRECTIVE
#pragma omp for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ ++a;
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
+ }
// SINGLE DIRECTIVE
#pragma omp single
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp single
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
// MASTER DIRECTIVE
#pragma omp master
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp master
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ ++a;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp critical
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
// PARALLEL FOR SIMD DIRECTIVE
#pragma omp parallel for simd
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ a++;
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel sections
+ {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ }
// TASK DIRECTIVE
#pragma omp task
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp task
+ {
+#pragma omp target update // // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ a++;
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{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-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ }
// TARGET DIRECTIVE
#pragma omp target
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{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-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ a++;
+ }
// TARGET PARALLEL DIRECTIVE
#pragma omp target parallel
{
#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
}
+#pragma omp target parallel
+ {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+
// TARGET PARALLEL FOR DIRECTIVE
#pragma omp target parallel for
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ a++;
+ }
// TEAMS DIRECTIVE
#pragma omp target
#pragma omp distribute
for (int j = 0; j < 10; ++j)
;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+ ++a;
+ }
// TASKLOOP DIRECTIVE
#pragma omp taskloop
for (int i = 0; i < 10; ++i)
++a;
}
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ ++a;
+ }
// DISTRIBUTE DIRECTIVE
#pragma omp target
#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
++a;
}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
}
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <class T, class S>
+int tmain(T argc, S **argv) {
+ int i;
+#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+}
+
+int main(int argc, char **argv) {
+ int j;
+#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+
+ return tmain(argc, argv);
+}
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %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) {
+ int n;
+#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (S) // expected-error {{'S' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int m;
+#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ return tmain(argc, argv);
+}
--- /dev/null
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // Aexpected-note {{declared here}}
+
+template <class T, class S> // Aexpected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ int n;
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int m;
+ #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+
+ #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ {
+ foo();
+ }
+ return tmain(argc, argv);
+}
return cxstring::createRef("OMPTargetParallelDirective");
case CXCursor_OMPTargetParallelForDirective:
return cxstring::createRef("OMPTargetParallelForDirective");
+ case CXCursor_OMPTargetUpdateDirective:
+ return cxstring::createRef("OMPTargetUpdateDirective");
case CXCursor_OMPTeamsDirective:
return cxstring::createRef("OMPTeamsDirective");
case CXCursor_OMPCancellationPointDirective:
case Stmt::OMPTargetParallelForDirectiveClass:
K = CXCursor_OMPTargetParallelForDirective;
break;
+ case Stmt::OMPTargetUpdateDirectiveClass:
+ K = CXCursor_OMPTargetUpdateDirective;
+ break;
case Stmt::OMPTeamsDirectiveClass:
K = CXCursor_OMPTeamsDirective;
break;