r213616 - [OPENMP] Initial parsing and sema analysis for 'ordered' directive.

Alexey Bataev a.bataev at hotmail.com
Mon Jul 21 23:45:05 PDT 2014


Author: abataev
Date: Tue Jul 22 01:45:04 2014
New Revision: 213616

URL: http://llvm.org/viewvc/llvm-project?rev=213616&view=rev
Log:
[OPENMP] Initial parsing and sema analysis for 'ordered' directive.

Added:
    cfe/trunk/test/OpenMP/ordered_ast_print.cpp   (with props)
    cfe/trunk/test/OpenMP/ordered_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/DiagnosticSemaKinds.td
    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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Jul 22 01:45:04 2014
@@ -2190,10 +2190,14 @@ enum CXCursorKind {
   /** \brief OpenMP flush directive.
    */
   CXCursor_OMPFlushDirective             = 246,
+  
+  /** \brief OpenMP ordered directive.
+   */
+  CXCursor_OMPOrderedDirective           = 247,
 
   /** \brief Windows Structured Exception Handling's leave statement.
    */
-  CXCursor_SEHLeaveStmt                  = 247,
+  CXCursor_SEHLeaveStmt                  = 248,
 
   CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
 

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Tue Jul 22 01:45:04 2014
@@ -2326,6 +2326,9 @@ DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
 DEF_TRAVERSE_STMT(OMPFlushDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+                  { 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul 22 01:45:04 2014
@@ -2348,6 +2348,9 @@ DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
 DEF_TRAVERSE_STMT(OMPFlushDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+                  { 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Tue Jul 22 01:45:04 2014
@@ -1028,6 +1028,53 @@ public:
   }
 };
 
+/// \brief This represents '#pragma omp ordered' directive.
+///
+/// \code
+/// #pragma omp ordered
+/// \endcode
+///
+class OMPOrderedDirective : 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.
+  ///
+  OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPOrderedDirective()
+      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPOrderedDirective *Create(const ASTContext &C,
+                                     SourceLocation StartLoc,
+                                     SourceLocation EndLoc,
+                                     Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPOrderedDirectiveClass;
+  }
+};
+
 } // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 22 01:45:04 2014
@@ -7123,7 +7123,8 @@ def err_omp_reduction_id_not_compatible
   "variable of type %0 is not valid for specified reduction operation">;
 def err_omp_prohibited_region : Error<
   "region cannot be%select{| closely}0 nested inside '%1' region"
-  "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2">;
+  "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|"
+  "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?}2">;
 def err_omp_prohibited_region_simd : Error<
   "OpenMP constructs may not be nested inside a simd region">;
 def err_omp_prohibited_region_critical_same_name : Error<

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Jul 22 01:45:04 2014
@@ -70,6 +70,7 @@ OPENMP_DIRECTIVE(taskyield)
 OPENMP_DIRECTIVE(barrier)
 OPENMP_DIRECTIVE(taskwait)
 OPENMP_DIRECTIVE(flush)
+OPENMP_DIRECTIVE(ordered)
 OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
 OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
 

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Tue Jul 22 01:45:04 2014
@@ -193,3 +193,4 @@ def OMPTaskyieldDirective : DStmt<OMPExe
 def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
 def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
 def OMPFlushDirective : DStmt<OMPExecutableDirective>;
+def OMPOrderedDirective : 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 22 01:45:04 2014
@@ -7395,6 +7395,10 @@ public:
   StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
                                        SourceLocation StartLoc,
                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
 
   OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                          Expr *Expr,

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Jul 22 01:45:04 2014
@@ -1355,6 +1355,7 @@ namespace clang {
       STMT_OMP_BARRIER_DIRECTIVE,
       STMT_OMP_TASKWAIT_DIRECTIVE,
       STMT_OMP_FLUSH_DIRECTIVE,
+      STMT_OMP_ORDERED_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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Tue Jul 22 01:45:04 2014
@@ -1678,3 +1678,23 @@ OMPFlushDirective *OMPFlushDirective::Cr
   return new (Mem) OMPFlushDirective(NumClauses);
 }
 
+OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation EndLoc,
+                                                 Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPOrderedDirective *Dir = new (Mem) OMPOrderedDirective(StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C,
+                                                      EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPOrderedDirective();
+}
+

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jul 22 01:45:04 2014
@@ -886,6 +886,11 @@ void StmtPrinter::VisitOMPFlushDirective
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
+  Indent() << "#pragma omp ordered";
+  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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 22 01:45:04 2014
@@ -431,6 +431,10 @@ void StmtProfiler::VisitOMPFlushDirectiv
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Jul 22 01:45:04 2014
@@ -268,6 +268,7 @@ bool clang::isAllowedClauseForDirective(
   case OMPD_taskyield:
   case OMPD_barrier:
   case OMPD_taskwait:
+  case OMPD_ordered:
     break;
   }
   return false;

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Jul 22 01:45:04 2014
@@ -221,6 +221,9 @@ void CodeGenFunction::EmitStmt(const Stm
   case Stmt::OMPFlushDirectiveClass:
     EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
     break;
+  case Stmt::OMPOrderedDirectiveClass:
+    EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));
+    break;
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Jul 22 01:45:04 2014
@@ -128,3 +128,7 @@ void CodeGenFunction::EmitOMPFlushDirect
   llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
 }
 
+void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
+  llvm_unreachable("CodeGen for 'omp ordered' 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 22 01:45:04 2014
@@ -1936,6 +1936,7 @@ public:
   void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
   void EmitOMPFlushDirective(const OMPFlushDirective &S);
+  void EmitOMPOrderedDirective(const OMPOrderedDirective &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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Jul 22 01:45:04 2014
@@ -92,6 +92,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   case OMPD_section:
   case OMPD_single:
   case OMPD_master:
+  case OMPD_ordered:
   case OMPD_critical:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
@@ -113,7 +114,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
-///         'barrier' | 'taskwait' | 'flush' {clause} annot_pragma_openmp_end
+///         'barrier' | 'taskwait' | 'flush' | 'ordered' {clause}
+///         annot_pragma_openmp_end
 ///
 StmtResult
 Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
@@ -176,7 +178,8 @@ Parser::ParseOpenMPDeclarativeOrExecutab
   case OMPD_critical:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
-  case OMPD_task: {
+  case OMPD_task:
+  case OMPD_ordered: {
     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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 22 01:45:04 2014
@@ -91,15 +91,16 @@ private:
     DeclarationNameInfo DirectiveName;
     Scope *CurScope;
     SourceLocation ConstructLoc;
+    bool OrderedRegion;
     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
                  Scope *CurScope, SourceLocation Loc)
         : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
           Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
-          ConstructLoc(Loc) {}
+          ConstructLoc(Loc), OrderedRegion(false) {}
     SharingMapTy()
         : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
           Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
-          ConstructLoc() {}
+          ConstructLoc(), OrderedRegion(false) {}
   };
 
   typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -194,6 +195,18 @@ public:
     return isOpenMPThreadPrivate(DVar.CKind);
   }
 
+  /// \brief Marks current region as ordered (it has an 'ordered' clause).
+  void setOrderedRegion(bool IsOrdered = true) {
+    Stack.back().OrderedRegion = IsOrdered;
+  }
+  /// \brief Returns true, if parent region is ordered (has associated
+  /// 'ordered' clause), false - otherwise.
+  bool isParentOrderedRegion() const {
+    if (Stack.size() > 2)
+      return Stack[Stack.size() - 2].OrderedRegion;
+    return false;
+  }
+
   Scope *getCurScope() const { return Stack.back().CurScope; }
   Scope *getCurScope() { return Stack.back().CurScope; }
   SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
@@ -1093,6 +1106,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
                              Params);
     break;
   }
+  case OMPD_ordered: {
+    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:
@@ -1123,6 +1144,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel         | barrier         | *                                  |
   // | parallel         | taskwait        | *                                  |
   // | parallel         | flush           | *                                  |
+  // | parallel         | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
@@ -1139,6 +1161,7 @@ static bool CheckNestingOfRegions(Sema &
   // | for              | barrier         | +                                  |
   // | for              | taskwait        | *                                  |
   // | for              | flush           | *                                  |
+  // | for              | ordered         | * (if construct is ordered)        |
   // +------------------+-----------------+------------------------------------+
   // | master           | parallel        | *                                  |
   // | master           | for             | +                                  |
@@ -1155,11 +1178,12 @@ static bool CheckNestingOfRegions(Sema &
   // | master           | barrier         | +                                  |
   // | master           | taskwait        | *                                  |
   // | master           | flush           | *                                  |
+  // | master           | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | critical         | parallel        | *                                  |
   // | critical         | for             | +                                  |
   // | critical         | master          | *                                  |
-  // | critical         | critical        | * (should have dirrerent names)    |
+  // | critical         | critical        | * (should have different names)    |
   // | critical         | simd            | *                                  |
   // | critical         | sections        | +                                  |
   // | critical         | section         | +                                  |
@@ -1170,6 +1194,7 @@ static bool CheckNestingOfRegions(Sema &
   // | critical         | taskyield       | *                                  |
   // | critical         | barrier         | +                                  |
   // | critical         | taskwait        | *                                  |
+  // | critical         | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | simd             | parallel        |                                    |
   // | simd             | for             |                                    |
@@ -1186,6 +1211,7 @@ static bool CheckNestingOfRegions(Sema &
   // | simd             | barrier         |                                    |
   // | simd             | taskwait        |                                    |
   // | simd             | flush           |                                    |
+  // | simd             | ordered         |                                    |
   // +------------------+-----------------+------------------------------------+
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
@@ -1202,6 +1228,7 @@ static bool CheckNestingOfRegions(Sema &
   // | sections         | barrier         | +                                  |
   // | sections         | taskwait        | *                                  |
   // | sections         | flush           | *                                  |
+  // | sections         | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
@@ -1218,6 +1245,7 @@ static bool CheckNestingOfRegions(Sema &
   // | section          | barrier         | +                                  |
   // | section          | taskwait        | *                                  |
   // | section          | flush           | *                                  |
+  // | section          | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
@@ -1234,6 +1262,7 @@ static bool CheckNestingOfRegions(Sema &
   // | single           | barrier         | +                                  |
   // | single           | taskwait        | *                                  |
   // | single           | flush           | *                                  |
+  // | single           | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
@@ -1250,6 +1279,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel for     | barrier         | +                                  |
   // | parallel for     | taskwait        | *                                  |
   // | parallel for     | flush           | *                                  |
+  // | parallel for     | ordered         | * (if construct is ordered)        |
   // +------------------+-----------------+------------------------------------+
   // | parallel sections| parallel        | *                                  |
   // | parallel sections| for             | +                                  |
@@ -1266,6 +1296,7 @@ static bool CheckNestingOfRegions(Sema &
   // | parallel sections| barrier         | +                                  |
   // | parallel sections| taskwait        | *                                  |
   // | parallel sections| flush           | *                                  |
+  // | parallel sections| ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
@@ -1282,12 +1313,34 @@ static bool CheckNestingOfRegions(Sema &
   // | task             | barrier         | +                                  |
   // | task             | taskwait        | *                                  |
   // | task             | flush           | *                                  |
+  // | task             | ordered         | +                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | ordered          | parallel        | *                                  |
+  // | ordered          | for             | +                                  |
+  // | ordered          | master          | *                                  |
+  // | ordered          | critical        | *                                  |
+  // | ordered          | simd            | *                                  |
+  // | ordered          | sections        | +                                  |
+  // | ordered          | section         | +                                  |
+  // | ordered          | single          | +                                  |
+  // | ordered          | parallel for    | *                                  |
+  // | ordered          |parallel sections| *                                  |
+  // | ordered          | task            | *                                  |
+  // | ordered          | taskyield       | *                                  |
+  // | ordered          | barrier         | +                                  |
+  // | ordered          | taskwait        | *                                  |
+  // | ordered          | flush           | *                                  |
+  // | ordered          | ordered         | +                                  |
   // +------------------+-----------------+------------------------------------+
   if (Stack->getCurScope()) {
     auto ParentRegion = Stack->getParentDirective();
     bool NestingProhibited = false;
     bool CloseNesting = true;
-    bool ShouldBeInParallelRegion = false;
+    enum {
+      NoRecommend,
+      ShouldBeInParallelRegion,
+      ShouldBeInOrderedRegion
+    } Recommend = NoRecommend;
     if (isOpenMPSimdDirective(ParentRegion)) {
       // OpenMP [2.16, Nesting of Regions]
       // OpenMP constructs may not be nested inside a simd region.
@@ -1308,6 +1361,10 @@ static bool CheckNestingOfRegions(Sema &
       }
       return false;
     }
+    // Allow some constructs to be orphaned (they could be used in functions,
+    // called from OpenMP regions with the required preconditions).
+    if (ParentRegion == OMPD_unknown)
+      return false;
     if (CurrentRegion == OMPD_master) {
       // OpenMP [2.16, Nesting of Regions]
       // A master region may not be closely nested inside a worksharing,
@@ -1346,12 +1403,11 @@ static bool CheckNestingOfRegions(Sema &
     } else if (CurrentRegion == OMPD_barrier) {
       // OpenMP [2.16, Nesting of Regions]
       // A barrier region may not be closely nested inside a worksharing,
-      // explicit task, critical, ordered(TODO), atomic(TODO), or master
-      // region.
-      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
-                          ParentRegion == OMPD_task ||
-                          ParentRegion == OMPD_master ||
-                          ParentRegion == OMPD_critical;
+      // explicit task, critical, ordered, atomic(TODO), or master region.
+      NestingProhibited =
+          isOpenMPWorksharingDirective(ParentRegion) ||
+          ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
+          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
                !isOpenMPParallelDirective(CurrentRegion) &&
                !isOpenMPSimdDirective(CurrentRegion)) {
@@ -1359,17 +1415,27 @@ static bool CheckNestingOfRegions(Sema &
       // A worksharing region may not be closely nested inside a worksharing,
       // explicit task, critical, ordered, atomic, or master region.
       // TODO
-      NestingProhibited = (isOpenMPWorksharingDirective(ParentRegion) &&
-                           !isOpenMPSimdDirective(ParentRegion)) ||
+      NestingProhibited =
+          (isOpenMPWorksharingDirective(ParentRegion) &&
+           !isOpenMPSimdDirective(ParentRegion)) ||
+          ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
+          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
+      Recommend = ShouldBeInParallelRegion;
+    } else if (CurrentRegion == OMPD_ordered) {
+      // OpenMP [2.16, Nesting of Regions]
+      // An ordered region may not be closely nested inside a critical,
+      // atomic(TODO), or explicit task region.
+      // An ordered region must be closely nested inside a loop region (or
+      // parallel loop region) with an ordered clause.
+      NestingProhibited = ParentRegion == OMPD_critical ||
                           ParentRegion == OMPD_task ||
-                          ParentRegion == OMPD_master ||
-                          ParentRegion == OMPD_critical;
-      ShouldBeInParallelRegion = true;
+                          !Stack->isParentOrderedRegion();
+      Recommend = ShouldBeInOrderedRegion;
     }
     if (NestingProhibited) {
       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
-          << CloseNesting << getOpenMPDirectiveName(ParentRegion)
-          << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion);
+          << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
+          << getOpenMPDirectiveName(CurrentRegion);
       return true;
     }
   }
@@ -1487,6 +1553,11 @@ StmtResult Sema::ActOnOpenMPExecutableDi
            "No associated statement allowed for 'omp flush' directive");
     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
     break;
+  case OMPD_ordered:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp ordered' directive");
+    Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc);
+    break;
   case OMPD_threadprivate:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
@@ -2264,6 +2335,16 @@ StmtResult Sema::ActOnOpenMPFlushDirecti
   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
 }
 
+StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
                                              SourceLocation StartLoc,
                                              SourceLocation LParenLoc,
@@ -2727,6 +2808,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
 
 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
                                           SourceLocation EndLoc) {
+  DSAStack->setOrderedRegion();
   return new (Context) OMPOrderedClause(StartLoc, EndLoc);
 }
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jul 22 01:45:04 2014
@@ -6633,6 +6633,17 @@ TreeTransform<Derived>::TransformOMPFlus
   return Res;
 }
 
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 22 01:45:04 2014
@@ -2031,6 +2031,11 @@ void ASTStmtReader::VisitOMPFlushDirecti
   VisitOMPExecutableDirective(D);
 }
 
+void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
 //===----------------------------------------------------------------------===//
 // ASTReader Implementation
 //===----------------------------------------------------------------------===//
@@ -2586,6 +2591,10 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
           Context, Record[ASTStmtReader::NumStmtFields], Empty);
       break;
 
+    case STMT_OMP_ORDERED_DIRECTIVE:
+      S = OMPOrderedDirective::CreateEmpty(Context, 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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 22 01:45:04 2014
@@ -1930,6 +1930,12 @@ void ASTStmtWriter::VisitOMPFlushDirecti
   Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
+}
+
 //===----------------------------------------------------------------------===//
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 22 01:45:04 2014
@@ -746,6 +746,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
     case Stmt::OMPBarrierDirectiveClass:
     case Stmt::OMPTaskwaitDirectiveClass:
     case Stmt::OMPFlushDirectiveClass:
+    case Stmt::OMPOrderedDirectiveClass:
       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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)
+++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Tue Jul 22 01:45:04 2014
@@ -71,6 +71,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp parallel
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -166,6 +171,11 @@ void foo() {
 #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     bar();
   }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
 
 // FOR DIRECTIVE
 #pragma omp for
@@ -279,6 +289,16 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK
+    bar();
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -404,6 +424,11 @@ void foo() {
   {
 #pragma omp flush
   }
+#pragma omp sections
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -550,6 +575,14 @@ void foo() {
       bar();
     }
   }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+      bar();
+    }
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -655,6 +688,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp single
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -760,6 +798,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp master
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -879,6 +922,11 @@ void foo() {
       }
     }
   }
+#pragma omp critical
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
@@ -994,6 +1042,16 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp parallel for ordered
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK
+    bar();
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -1105,6 +1163,11 @@ void foo() {
   {
 #pragma omp flush
   }
+#pragma omp parallel sections
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -1169,6 +1232,114 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp task
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+
+// ORDERED DIRECTIVE
+#pragma omp ordered
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp master // OK, though second 'ordered' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp parallel for ordered
+    for (int j = 0; j < 10; ++j) {
+#pragma omp ordered // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp ordered
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp ordered
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'ordered' region}}
+    bar();
+  }
+#pragma omp ordered
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp ordered
+  {
+#pragma omp flush
+    bar();
+  }
+#pragma omp ordered
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 }
 
 void foo() {
@@ -1239,6 +1410,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp parallel
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -1327,6 +1503,11 @@ void foo() {
 #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     bar();
   }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
 
 // FOR DIRECTIVE
 #pragma omp for
@@ -1427,6 +1608,16 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK
+    bar();
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -1524,6 +1715,11 @@ void foo() {
   {
 #pragma omp flush
   }
+#pragma omp sections
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -1670,6 +1866,14 @@ void foo() {
       bar();
     }
   }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+      bar();
+    }
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -1765,6 +1969,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp single
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -1870,6 +2079,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp master
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -1989,6 +2203,11 @@ void foo() {
       }
     }
   }
+#pragma omp critical
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
@@ -2103,6 +2322,16 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp parallel for ordered
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK 
+    bar();
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -2210,6 +2439,11 @@ void foo() {
   {
 #pragma omp flush
   }
+#pragma omp parallel sections
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -2273,6 +2507,11 @@ void foo() {
 #pragma omp flush
     bar();
   }
+#pragma omp task
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
   return foo<int>();
 }
 

Added: cfe/trunk/test/OpenMP/ordered_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_ast_print.cpp?rev=213616&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/ordered_ast_print.cpp (added)
+++ cfe/trunk/test/OpenMP/ordered_ast_print.cpp Tue Jul 22 01:45:04 2014
@@ -0,0 +1,59 @@
+// 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 <class T>
+T tmain (T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+  #pragma omp for ordered
+  for (int i =0 ; i < argc; ++i)
+  #pragma omp ordered
+  {
+    a=2;
+  }
+  return (0);
+}
+
+// CHECK: static int a;
+// CHECK-NEXT: #pragma omp for ordered
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+
+// CHECK: static T a;
+// CHECK-NEXT: #pragma omp for ordered
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+  #pragma omp for ordered
+  for (int i =0 ; i < argc; ++i)
+  #pragma omp ordered
+  {
+    a=2;
+  }
+// CHECK-NEXT: #pragma omp for ordered
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+  return tmain(argc);
+}
+
+#endif

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

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

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

Added: cfe/trunk/test/OpenMP/ordered_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_messages.cpp?rev=213616&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/ordered_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/ordered_messages.cpp Tue Jul 22 01:45:04 2014
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+int foo();
+
+template <class T>
+T foo() {
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+    L1:
+      foo();
+    #pragma omp ordered
+    {
+      foo();
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    }
+  }
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+    #pragma omp ordered
+    {
+      L2:
+      foo();
+    }
+  }
+
+  return T();
+}
+
+int foo() {
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+    L1:
+      foo();
+    #pragma omp ordered
+    {
+      foo();
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    }
+  }
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+    #pragma omp ordered
+    {
+      L2:
+      foo();
+    }
+  }
+
+  return foo<int>();
+}

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

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

Propchange: cfe/trunk/test/OpenMP/ordered_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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 22 01:45:04 2014
@@ -1871,6 +1871,7 @@ public:
   void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
   void VisitOMPFlushDirective(const OMPFlushDirective *D);
+  void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
 
 private:
   void AddDeclarationNameInfo(const Stmt *S);
@@ -2373,6 +2374,10 @@ void EnqueueVisitor::VisitOMPFlushDirect
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
 }
@@ -4075,6 +4080,8 @@ CXString clang_getCursorKindSpelling(enu
     return cxstring::createRef("OMPTaskwaitDirective");
   case CXCursor_OMPFlushDirective:
     return cxstring::createRef("OMPFlushDirective");
+  case CXCursor_OMPOrderedDirective:
+    return cxstring::createRef("OMPOrderedDirective");
   }
 
   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=213616&r1=213615&r2=213616&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Jul 22 01:45:04 2014
@@ -562,6 +562,9 @@ CXCursor cxcursor::MakeCXCursor(const St
   case Stmt::OMPFlushDirectiveClass:
     K = CXCursor_OMPFlushDirective;
     break;
+  case Stmt::OMPOrderedDirectiveClass:
+    K = CXCursor_OMPOrderedDirective;
+    break;
   }
 
   CXCursor C = { K, 0, { Parent, S, TU } };





More information about the cfe-commits mailing list