r218110 - [OPENMP] Initial parsing/sema analysis of 'target' directive.

Alexey Bataev a.bataev at hotmail.com
Fri Sep 19 01:19:50 PDT 2014


Author: abataev
Date: Fri Sep 19 03:19:49 2014
New Revision: 218110

URL: http://llvm.org/viewvc/llvm-project?rev=218110&view=rev
Log:
[OPENMP] Initial parsing/sema analysis of 'target' directive.

Added:
    cfe/trunk/test/OpenMP/target_ast_print.cpp   (with props)
    cfe/trunk/test/OpenMP/target_if_messages.cpp   (with props)
    cfe/trunk/test/OpenMP/target_messages.cpp   (with props)
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/StmtOpenMP.h
    cfe/trunk/include/clang/Basic/OpenMPKinds.def
    cfe/trunk/include/clang/Basic/StmtNodes.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Basic/OpenMPKinds.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Parse/ParseOpenMP.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/OpenMP/nesting_of_regions.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri Sep 19 03:19:49 2014
@@ -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.

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Fri Sep 19 03:19:49 2014
@@ -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) {

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Sep 19 03:19:49 2014
@@ -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) {

Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Fri Sep 19 03:19:49 2014
@@ -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

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Fri Sep 19 03:19:49 2014
@@ -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

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Fri Sep 19 03:19:49 2014
@@ -197,3 +197,4 @@ def OMPTaskwaitDirective : DStmt<OMPExec
 def OMPFlushDirective : DStmt<OMPExecutableDirective>;
 def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
 def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetDirective : DStmt<OMPExecutableDirective>;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Sep 19 03:19:49 2014
@@ -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,

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Sep 19 03:19:49 2014
@@ -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

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Fri Sep 19 03:19:49 2014
@@ -1788,3 +1788,29 @@ OMPAtomicDirective *OMPAtomicDirective::
   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);
+}
+

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Sep 19 03:19:49 2014
@@ -917,6 +917,11 @@ void StmtPrinter::VisitOMPAtomicDirectiv
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
+  Indent() << "#pragma omp target ";
+  PrintOMPExecutableDirective(Node);
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Fri Sep 19 03:19:49 2014
@@ -457,6 +457,10 @@ void StmtProfiler::VisitOMPAtomicDirecti
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
 void StmtProfiler::VisitExpr(const Expr *S) {
   VisitStmt(S);
 }

Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Fri Sep 19 03:19:49 2014
@@ -294,6 +294,16 @@ bool clang::isAllowedClauseForDirective(
       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:

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Fri Sep 19 03:19:49 2014
@@ -230,6 +230,9 @@ void CodeGenFunction::EmitStmt(const Stm
   case Stmt::OMPAtomicDirectiveClass:
     EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));
     break;
+  case Stmt::OMPTargetDirectiveClass:
+    EmitOMPTargetDirective(cast<OMPTargetDirective>(*S));
+    break;
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Fri Sep 19 03:19:49 2014
@@ -140,3 +140,7 @@ void CodeGenFunction::EmitOMPAtomicDirec
   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.");
+}
+

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Sep 19 03:19:49 2014
@@ -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

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri Sep 19 03:19:49 2014
@@ -105,6 +105,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   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::ParseOpen
 ///         '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::ParseOpenMPDeclarativeOrExecutab
   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) {

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Sep 19 03:19:49 2014
@@ -1132,6 +1132,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
                              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 &
   // | parallel         | flush           | *                                  |
   // | parallel         | ordered         | +                                  |
   // | parallel         | atomic          | *                                  |
+  // | parallel         | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
@@ -1184,6 +1193,7 @@ static bool CheckNestingOfRegions(Sema &
   // | for              | flush           | *                                  |
   // | for              | ordered         | * (if construct is ordered)        |
   // | for              | atomic          | *                                  |
+  // | for              | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | master           | parallel        | *                                  |
   // | master           | for             | +                                  |
@@ -1203,6 +1213,7 @@ static bool CheckNestingOfRegions(Sema &
   // | master           | flush           | *                                  |
   // | master           | ordered         | +                                  |
   // | master           | atomic          | *                                  |
+  // | master           | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | critical         | parallel        | *                                  |
   // | critical         | for             | +                                  |
@@ -1221,6 +1232,7 @@ static bool CheckNestingOfRegions(Sema &
   // | critical         | taskwait        | *                                  |
   // | critical         | ordered         | +                                  |
   // | critical         | atomic          | *                                  |
+  // | critical         | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | simd             | parallel        |                                    |
   // | simd             | for             |                                    |
@@ -1240,6 +1252,7 @@ static bool CheckNestingOfRegions(Sema &
   // | simd             | flush           |                                    |
   // | simd             | ordered         |                                    |
   // | simd             | atomic          |                                    |
+  // | simd             | target          |                                    |
   // +------------------+-----------------+------------------------------------+
   // | for simd         | parallel        |                                    |
   // | for simd         | for             |                                    |
@@ -1259,6 +1272,7 @@ static bool CheckNestingOfRegions(Sema &
   // | for simd         | flush           |                                    |
   // | for simd         | ordered         |                                    |
   // | for simd         | atomic          |                                    |
+  // | for simd         | target          |                                    |
   // +------------------+-----------------+------------------------------------+
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
@@ -1278,6 +1292,7 @@ static bool CheckNestingOfRegions(Sema &
   // | sections         | flush           | *                                  |
   // | sections         | ordered         | +                                  |
   // | sections         | atomic          | *                                  |
+  // | sections         | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
@@ -1297,6 +1312,7 @@ static bool CheckNestingOfRegions(Sema &
   // | section          | flush           | *                                  |
   // | section          | ordered         | +                                  |
   // | section          | atomic          | *                                  |
+  // | section          | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
@@ -1316,6 +1332,7 @@ static bool CheckNestingOfRegions(Sema &
   // | single           | flush           | *                                  |
   // | single           | ordered         | +                                  |
   // | single           | atomic          | *                                  |
+  // | single           | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
@@ -1335,6 +1352,7 @@ static bool CheckNestingOfRegions(Sema &
   // | 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 &
   // | parallel sections| flush           | *                                  |
   // | parallel sections| ordered         | +                                  |
   // | parallel sections| atomic          | *                                  |
+  // | parallel sections| target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
@@ -1373,6 +1392,7 @@ static bool CheckNestingOfRegions(Sema &
   // | task             | flush           | *                                  |
   // | task             | ordered         | +                                  |
   // | task             | atomic          | *                                  |
+  // | task             | target          | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | ordered          | parallel        | *                                  |
   // | ordered          | for             | +                                  |
@@ -1392,6 +1412,47 @@ static bool CheckNestingOfRegions(Sema &
   // | 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::ActOnOpenMPExecutableDi
     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::ActOnOpenMPAtomicDirect
   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,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Sep 19 03:19:49 2014
@@ -6663,6 +6663,17 @@ TreeTransform<Derived>::TransformOMPAtom
   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
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Fri Sep 19 03:19:49 2014
@@ -2072,6 +2072,13 @@ void ASTStmtReader::VisitOMPAtomicDirect
   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(Modu
           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;

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri Sep 19 03:19:49 2014
@@ -1931,6 +1931,13 @@ void ASTStmtWriter::VisitOMPAtomicDirect
   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);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Sep 19 03:19:49 2014
@@ -816,6 +816,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
     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:

Modified: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nesting_of_regions.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)
+++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Fri Sep 19 03:19:49 2014
@@ -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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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>();
 }
 

Added: cfe/trunk/test/OpenMP/target_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_ast_print.cpp?rev=218110&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/target_ast_print.cpp (added)
+++ cfe/trunk/test/OpenMP/target_ast_print.cpp Fri Sep 19 03:19:49 2014
@@ -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

Propchange: cfe/trunk/test/OpenMP/target_ast_print.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/OpenMP/target_ast_print.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/OpenMP/target_ast_print.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/OpenMP/target_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_if_messages.cpp?rev=218110&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/target_if_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/target_if_messages.cpp Fri Sep 19 03:19:49 2014
@@ -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);
+}

Propchange: cfe/trunk/test/OpenMP/target_if_messages.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/OpenMP/target_if_messages.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/OpenMP/target_if_messages.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/OpenMP/target_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_messages.cpp?rev=218110&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/target_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/target_messages.cpp Fri Sep 19 03:19:49 2014
@@ -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 at +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;
+}
+

Propchange: cfe/trunk/test/OpenMP/target_messages.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/OpenMP/target_messages.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/OpenMP/target_messages.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Sep 19 03:19:49 2014
@@ -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::VisitOMPAtomicDirec
   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(enu
     return cxstring::createRef("OMPOrderedDirective");
   case CXCursor_OMPAtomicDirective:
     return cxstring::createRef("OMPAtomicDirective");
+  case CXCursor_OMPTargetDirective:
+    return cxstring::createRef("OMPTargetDirective");
   }
 
   llvm_unreachable("Unhandled CXCursorKind");

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=218110&r1=218109&r2=218110&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Fri Sep 19 03:19:49 2014
@@ -572,6 +572,9 @@ CXCursor cxcursor::MakeCXCursor(const St
   case Stmt::OMPAtomicDirectiveClass:
     K = CXCursor_OMPAtomicDirective;
     break;
+  case Stmt::OMPTargetDirectiveClass:
+    K = CXCursor_OMPTargetDirective;
+    break;
   }
 
   CXCursor C = { K, 0, { Parent, S, TU } };





More information about the cfe-commits mailing list