summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang-c/Index.h6
-rw-r--r--clang/include/clang/AST/DataRecursiveASTVisitor.h3
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h3
-rw-r--r--clang/include/clang/AST/StmtOpenMP.h57
-rw-r--r--clang/include/clang/Basic/OpenMPKinds.def9
-rw-r--r--clang/include/clang/Basic/StmtNodes.td1
-rw-r--r--clang/include/clang/Sema/Sema.h6
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h1
-rw-r--r--clang/lib/AST/Stmt.cpp26
-rw-r--r--clang/lib/AST/StmtPrinter.cpp5
-rw-r--r--clang/lib/AST/StmtProfile.cpp4
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp10
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp3
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h1
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp6
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp76
-rw-r--r--clang/lib/Sema/TreeTransform.h11
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp12
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp1
-rw-r--r--clang/test/OpenMP/nesting_of_regions.cpp393
-rw-r--r--clang/test/OpenMP/target_ast_print.cpp57
-rw-r--r--clang/test/OpenMP/target_if_messages.cpp46
-rw-r--r--clang/test/OpenMP/target_messages.cpp64
-rw-r--r--clang/tools/libclang/CIndex.cpp7
-rw-r--r--clang/tools/libclang/CXCursor.cpp3
27 files changed, 783 insertions, 39 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index a86171aaba9..3f7f13cb069 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2213,7 +2213,11 @@ enum CXCursorKind {
*/
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.
diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h
index 0612231e915..b06fb255252 100644
--- a/clang/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h
@@ -2342,6 +2342,9 @@ DEF_TRAVERSE_STMT(OMPOrderedDirective,
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) {
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 19c01e0212f..cf2b4156a33 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2364,6 +2364,9 @@ DEF_TRAVERSE_STMT(OMPOrderedDirective,
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) {
diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index 54df0eaf471..cbb87355062 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -1215,6 +1215,63 @@ public:
}
};
+/// \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
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index cda95abc9e3..2c31307119b 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -51,6 +51,9 @@
#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
@@ -78,6 +81,7 @@ OPENMP_DIRECTIVE(taskwait)
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")
@@ -226,6 +230,10 @@ OPENMP_ATOMIC_CLAUSE(update)
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
@@ -239,6 +247,7 @@ OPENMP_ATOMIC_CLAUSE(seq_cst)
#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
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index c967d3ff47e..81c113e6bf4 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -197,3 +197,4 @@ def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
def OMPFlushDirective : DStmt<OMPExecutableDirective>;
def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetDirective : DStmt<OMPExecutableDirective>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b262c45cd7c..0e5ed350a77 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7466,6 +7466,12 @@ public:
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,
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index d209bcc8769..0e13a910f65 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1358,6 +1358,7 @@ namespace clang {
STMT_OMP_FLUSH_DIRECTIVE,
STMT_OMP_ORDERED_DIRECTIVE,
STMT_OMP_ATOMIC_DIRECTIVE,
+ STMT_OMP_TARGET_DIRECTIVE,
// ARC
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index e966ee83bbd..f2efca86644 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1788,3 +1788,29 @@ OMPAtomicDirective *OMPAtomicDirective::CreateEmpty(const ASTContext &C,
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);
+}
+
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 50715e68c26..d065c62feab 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -917,6 +917,11 @@ void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
+ Indent() << "#pragma omp target ";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 9d2d69fa282..cc61fae276f 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -457,6 +457,10 @@ void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index b0043d5e486..7394d0bbb18 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -294,6 +294,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_target:
+ switch (CKind) {
+#define OPENMP_TARGET_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_unknown:
case OMPD_threadprivate:
case OMPD_section:
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 560ce608bee..7be6759df42 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -230,6 +230,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::OMPAtomicDirectiveClass:
EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));
break;
+ case Stmt::OMPTargetDirectiveClass:
+ EmitOMPTargetDirective(cast<OMPTargetDirective>(*S));
+ break;
}
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 3597dddd99a..74b73a55603 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -140,3 +140,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
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.");
+}
+
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index eebdbf34a8e..4e89725a600 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1943,6 +1943,7 @@ public:
void EmitOMPFlushDirective(const OMPFlushDirective &S);
void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
+ void EmitOMPTargetDirective(const OMPTargetDirective &S);
//===--------------------------------------------------------------------===//
// LValue Expression Emission
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index dd776773f42..45f6da0d059 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -105,6 +105,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
case OMPD_parallel_for:
case OMPD_parallel_sections:
case OMPD_atomic:
+ case OMPD_target:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
break;
@@ -124,7 +125,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
/// '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
@@ -191,7 +192,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
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) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 5c78804239e..30d873efcc6 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1132,6 +1132,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
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:
@@ -1165,6 +1173,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel | flush | * |
// | parallel | ordered | + |
// | parallel | atomic | * |
+ // | parallel | target | * |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
@@ -1184,6 +1193,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | flush | * |
// | for | ordered | * (if construct is ordered) |
// | for | atomic | * |
+ // | for | target | * |
// +------------------+-----------------+------------------------------------+
// | master | parallel | * |
// | master | for | + |
@@ -1203,6 +1213,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | master | flush | * |
// | master | ordered | + |
// | master | atomic | * |
+ // | master | target | * |
// +------------------+-----------------+------------------------------------+
// | critical | parallel | * |
// | critical | for | + |
@@ -1221,6 +1232,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | critical | taskwait | * |
// | critical | ordered | + |
// | critical | atomic | * |
+ // | critical | target | * |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
@@ -1240,6 +1252,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | flush | |
// | simd | ordered | |
// | simd | atomic | |
+ // | simd | target | |
// +------------------+-----------------+------------------------------------+
// | for simd | parallel | |
// | for simd | for | |
@@ -1259,6 +1272,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for simd | flush | |
// | for simd | ordered | |
// | for simd | atomic | |
+ // | for simd | target | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
@@ -1278,6 +1292,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | sections | flush | * |
// | sections | ordered | + |
// | sections | atomic | * |
+ // | sections | target | * |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
@@ -1297,6 +1312,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | section | flush | * |
// | section | ordered | + |
// | section | atomic | * |
+ // | section | target | * |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
@@ -1316,6 +1332,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | single | flush | * |
// | single | ordered | + |
// | single | atomic | * |
+ // | single | target | * |
// +------------------+-----------------+------------------------------------+
// | parallel for | parallel | * |
// | parallel for | for | + |
@@ -1335,6 +1352,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for | flush | * |
// | parallel for | ordered | * (if construct is ordered) |
// | parallel for | atomic | * |
+ // | parallel for | target | * |
// +------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * |
// | parallel sections| for | + |
@@ -1354,6 +1372,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel sections| flush | * |
// | parallel sections| ordered | + |
// | parallel sections| atomic | * |
+ // | parallel sections| target | * |
// +------------------+-----------------+------------------------------------+
// | task | parallel | * |
// | task | for | + |
@@ -1373,6 +1392,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | task | flush | * |
// | task | ordered | + |
// | task | atomic | * |
+ // | task | target | * |
// +------------------+-----------------+------------------------------------+
// | ordered | parallel | * |
// | ordered | for | + |
@@ -1392,6 +1412,47 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | 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();
@@ -1630,6 +1691,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
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:
@@ -2512,6 +2577,17 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
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,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 92baa0ebd22..9dfa8b73e0d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6663,6 +6663,17 @@ TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
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
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index eefdcdf04c4..ff7a53e22f8 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2072,6 +2072,13 @@ void ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPTargetDirective(OMPTargetDirective *D) {
+ VisitStmt(D);
+ // The NumClauses field was read in ReadStmtFromStream.
+ ++Idx;
+ VisitOMPExecutableDirective(D);
+}
+
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
@@ -2644,6 +2651,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
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;
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 9873eda75f5..759f7f3ade7 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1931,6 +1931,13 @@ void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
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);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index a80b2de70d5..f85b004f087 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -816,6 +816,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
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:
diff --git a/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp
index eac2db215a2..203026b2f75 100644
--- a/clang/test/OpenMP/nesting_of_regions.cpp
+++ b/clang/test/OpenMP/nesting_of_regions.cpp
@@ -86,6 +86,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp parallel
+ {
+#pragma omp target
+ ++a;
+ }
// SIMD DIRECTIVE
#pragma omp simd
@@ -197,6 +202,11 @@ void foo() {
#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
@@ -331,6 +341,11 @@ void foo() {
#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
@@ -442,6 +457,11 @@ void foo() {
#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
@@ -583,6 +603,11 @@ void foo() {
#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}}
@@ -755,6 +780,12 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp target
+ ++a;
+ }
// SINGLE DIRECTIVE
#pragma omp single
@@ -879,6 +910,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp single
+ {
+#pragma omp target
+ ++a;
+ }
// MASTER DIRECTIVE
#pragma omp master
@@ -1003,6 +1039,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp master
+ {
+#pragma omp target
+ ++a;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
@@ -1141,6 +1182,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp critical
+ {
+#pragma omp target
+ ++a;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
@@ -1280,6 +1326,11 @@ void foo() {
#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
@@ -1410,6 +1461,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp parallel sections
+ {
+#pragma omp target
+ ++a;
+ }
// TASK DIRECTIVE
#pragma omp task
@@ -1488,6 +1544,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp task
+ {
+#pragma omp target
+ ++a;
+ }
// ORDERED DIRECTIVE
#pragma omp ordered
@@ -1602,38 +1663,43 @@ void foo() {
#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}}
{
@@ -1641,7 +1707,7 @@ void foo() {
}
}
#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}}
{
@@ -1649,7 +1715,7 @@ void foo() {
}
}
#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}}
{
@@ -1657,7 +1723,7 @@ void foo() {
}
}
#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}}
{
@@ -1665,7 +1731,7 @@ void foo() {
}
}
#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}}
{
@@ -1673,14 +1739,14 @@ void foo() {
}
}
#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}}
{
@@ -1688,7 +1754,7 @@ void foo() {
}
}
#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}}
{
@@ -1696,41 +1762,137 @@ void foo() {
}
}
#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() {
@@ -1816,6 +1978,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp parallel
+ {
+#pragma omp target
+ ++a;
+ }
// SIMD DIRECTIVE
#pragma omp simd
@@ -1920,6 +2087,11 @@ void foo() {
#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
@@ -2044,6 +2216,11 @@ void foo() {
#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
@@ -2148,6 +2325,11 @@ void foo() {
#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
@@ -2264,6 +2446,11 @@ void foo() {
#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}}
@@ -2438,6 +2625,14 @@ void foo() {
++a;
}
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target
+ ++a;
+ }
+ }
// SINGLE DIRECTIVE
#pragma omp single
@@ -2552,6 +2747,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp single
+ {
+#pragma omp target
+ ++a;
+ }
// MASTER DIRECTIVE
#pragma omp master
@@ -2676,6 +2876,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp master
+ {
+#pragma omp target
+ ++a;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
@@ -2819,6 +3024,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp critical
+ {
+#pragma omp target
+ ++a;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
@@ -2958,6 +3168,11 @@ void foo() {
#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
@@ -3084,6 +3299,11 @@ void foo() {
#pragma omp atomic
++a;
}
+#pragma omp parallel sections
+ {
+#pragma omp target
+ ++a;
+ }
// TASK DIRECTIVE
#pragma omp task
@@ -3161,38 +3381,43 @@ void foo() {
#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}}
{
@@ -3200,7 +3425,7 @@ void foo() {
}
}
#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}}
{
@@ -3208,7 +3433,7 @@ void foo() {
}
}
#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}}
{
@@ -3216,7 +3441,7 @@ void foo() {
}
}
#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}}
{
@@ -3224,7 +3449,7 @@ void foo() {
}
}
#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}}
{
@@ -3232,14 +3457,14 @@ void foo() {
}
}
#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}}
{
@@ -3247,7 +3472,7 @@ void foo() {
}
}
#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}}
{
@@ -3255,41 +3480,137 @@ void foo() {
}
}
#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>();
}
diff --git a/clang/test/OpenMP/target_ast_print.cpp b/clang/test/OpenMP/target_ast_print.cpp
new file mode 100644
index 00000000000..c57c04955f8
--- /dev/null
+++ b/clang/test/OpenMP/target_ast_print.cpp
@@ -0,0 +1,57 @@
+// 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
diff --git a/clang/test/OpenMP/target_if_messages.cpp b/clang/test/OpenMP/target_if_messages.cpp
new file mode 100644
index 00000000000..50a9ed2a202
--- /dev/null
+++ b/clang/test/OpenMP/target_if_messages.cpp
@@ -0,0 +1,46 @@
+// 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);
+}
diff --git a/clang/test/OpenMP/target_messages.cpp b/clang/test/OpenMP/target_messages.cpp
new file mode 100644
index 00000000000..fb492281e2b
--- /dev/null
+++ b/clang/test/OpenMP/target_messages.cpp
@@ -0,0 +1,64 @@
+// 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;
+}
+
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 1c97845462e..6d241170ca8 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1879,6 +1879,7 @@ public:
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);
@@ -2407,6 +2408,10 @@ void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
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);
}
@@ -4172,6 +4177,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OMPOrderedDirective");
case CXCursor_OMPAtomicDirective:
return cxstring::createRef("OMPAtomicDirective");
+ case CXCursor_OMPTargetDirective:
+ return cxstring::createRef("OMPTargetDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 96e8f993f66..d83e71a99ac 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -572,6 +572,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::OMPAtomicDirectiveClass:
K = CXCursor_OMPAtomicDirective;
break;
+ case Stmt::OMPTargetDirectiveClass:
+ K = CXCursor_OMPTargetDirective;
+ break;
}
CXCursor C = { K, 0, { Parent, S, TU } };
OpenPOWER on IntegriCloud