r213510 - [OPENMP] Parsing/Sema of the OpenMP directive 'critical'.

Alexander Musman alexander.musman at gmail.com
Mon Jul 21 02:42:06 PDT 2014


Author: amusman
Date: Mon Jul 21 04:42:05 2014
New Revision: 213510

URL: http://llvm.org/viewvc/llvm-project?rev=213510&view=rev
Log:
[OPENMP] Parsing/Sema of the OpenMP directive 'critical'.

Added:
    cfe/trunk/test/OpenMP/critical_ast_print.cpp
    cfe/trunk/test/OpenMP/critical_messages.cpp
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/DiagnosticParseKinds.td
    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=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Jul 21 04:42:05 2014
@@ -2171,21 +2171,25 @@ enum CXCursorKind {
    */
   CXCursor_OMPMasterDirective            = 241,
 
+  /** \brief OpenMP critical directive.
+   */
+  CXCursor_OMPCriticalDirective          = 242,
+
   /** \brief OpenMP taskyield directive.
    */
-  CXCursor_OMPTaskyieldDirective         = 242,
+  CXCursor_OMPTaskyieldDirective         = 243,
 
   /** \brief OpenMP barrier directive.
    */
-  CXCursor_OMPBarrierDirective           = 243,
+  CXCursor_OMPBarrierDirective           = 244,
 
   /** \brief OpenMP taskwait directive.
    */
-  CXCursor_OMPTaskwaitDirective          = 244,
+  CXCursor_OMPTaskwaitDirective          = 245,
 
   /** \brief Windows Structured Exception Handling's leave statement.
    */
-  CXCursor_SEHLeaveStmt                  = 245,
+  CXCursor_SEHLeaveStmt                  = 246,
 
   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=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Mon Jul 21 04:42:05 2014
@@ -2300,6 +2300,11 @@ DEF_TRAVERSE_STMT(OMPSingleDirective,
 DEF_TRAVERSE_STMT(OMPMasterDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
 DEF_TRAVERSE_STMT(OMPParallelForDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jul 21 04:42:05 2014
@@ -2322,6 +2322,11 @@ DEF_TRAVERSE_STMT(OMPSingleDirective,
 DEF_TRAVERSE_STMT(OMPMasterDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
 DEF_TRAVERSE_STMT(OMPParallelForDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 

Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Mon Jul 21 04:42:05 2014
@@ -585,6 +585,69 @@ public:
   }
 };
 
+/// \brief This represents '#pragma omp critical' directive.
+///
+/// \code
+/// #pragma omp critical
+/// \endcode
+///
+class OMPCriticalDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Name of the directive.
+  DeclarationNameInfo DirName;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
+                       SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               StartLoc, EndLoc, 0, 1),
+        DirName(Name) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPCriticalDirective()
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               SourceLocation(), SourceLocation(), 0, 1),
+        DirName() {}
+
+  /// \brief Set name of the directive.
+  ///
+  /// \param Name Name of the directive.
+  ///
+  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPCriticalDirective *
+  Create(const ASTContext &C, const DeclarationNameInfo &Name,
+         SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  /// \brief Return name of the directive.
+  ///
+  DeclarationNameInfo getDirectiveName() const { return DirName; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPCriticalDirectiveClass;
+  }
+};
+
 /// \brief This represents '#pragma omp parallel for' directive.
 ///
 /// \code

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Jul 21 04:42:05 2014
@@ -910,6 +910,8 @@ def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause">;
 def err_omp_immediate_directive : Error<
   "'#pragma omp %0' cannot be an immediate substatement">;
+def err_omp_expected_identifier_for_critical : Error<
+  "expected identifier specifying the name of the 'omp critical' directive">;
 
 // Pragma loop support.
 def err_pragma_loop_invalid_option : Error<

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul 21 04:42:05 2014
@@ -7127,6 +7127,10 @@ def err_omp_prohibited_region : Error<
   "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}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<
+  "cannot nest 'critical' regions having the same name %0">;
+def note_omp_previous_critical_region : Note<
+  "previous 'critical' region starts here">;
 def err_omp_sections_not_compound_stmt : Error<
   "the statement for '#pragma omp sections' must be a compound statement">;
 def err_omp_parallel_sections_not_compound_stmt : Error<

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Mon Jul 21 04:42:05 2014
@@ -65,6 +65,7 @@ OPENMP_DIRECTIVE(sections)
 OPENMP_DIRECTIVE(section)
 OPENMP_DIRECTIVE(single)
 OPENMP_DIRECTIVE(master)
+OPENMP_DIRECTIVE(critical)
 OPENMP_DIRECTIVE(taskyield)
 OPENMP_DIRECTIVE(barrier)
 OPENMP_DIRECTIVE(taskwait)

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Mon Jul 21 04:42:05 2014
@@ -185,6 +185,7 @@ def OMPSectionsDirective : DStmt<OMPExec
 def OMPSectionDirective : DStmt<OMPExecutableDirective>;
 def OMPSingleDirective : DStmt<OMPExecutableDirective>;
 def OMPMasterDirective : DStmt<OMPExecutableDirective>;
+def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
 def OMPParallelForDirective : DStmt<OMPExecutableDirective>;
 def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
 def OMPTaskDirective : 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=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul 21 04:42:05 2014
@@ -7303,14 +7303,15 @@ public:
   DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
                                      SourceLocation Loc,
                                      ArrayRef<Expr *> VarList);
-  // \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
+  /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
   OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
                                      SourceLocation Loc,
                                      ArrayRef<Expr *> VarList);
 
-  // brief Initialization of captured region for OpenMP region.
+  /// \brief Initialization of captured region for OpenMP region.
   void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
   StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                            const DeclarationNameInfo &DirName,
                                             ArrayRef<OMPClause *> Clauses,
                                             Stmt *AStmt,
                                             SourceLocation StartLoc,
@@ -7351,6 +7352,11 @@ public:
   /// associated statement.
   StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp critical' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
   /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
   /// of the  associated statement.
   StmtResult ActOnOpenMPParallelForDirective(

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Jul 21 04:42:05 2014
@@ -1347,6 +1347,7 @@ namespace clang {
       STMT_OMP_SECTION_DIRECTIVE,
       STMT_OMP_SINGLE_DIRECTIVE,
       STMT_OMP_MASTER_DIRECTIVE,
+      STMT_OMP_CRITICAL_DIRECTIVE,
       STMT_OMP_PARALLEL_FOR_DIRECTIVE,
       STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
       STMT_OMP_TASK_DIRECTIVE,

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Mon Jul 21 04:42:05 2014
@@ -1496,6 +1496,26 @@ OMPMasterDirective *OMPMasterDirective::
   return new (Mem) OMPMasterDirective();
 }
 
+OMPCriticalDirective *OMPCriticalDirective::Create(
+    const ASTContext &C, const DeclarationNameInfo &Name,
+    SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPCriticalDirective *Dir =
+      new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
+                                                        EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPCriticalDirective();
+}
+
 OMPParallelForDirective *
 OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation EndLoc, unsigned CollapsedNum,

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jul 21 04:42:05 2014
@@ -834,6 +834,16 @@ void StmtPrinter::VisitOMPMasterDirectiv
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
+  Indent() << "#pragma omp critical";
+  if (Node->getDirectiveName().getName()) {
+    OS << " (";
+    Node->getDirectiveName().printName(OS);
+    OS << ")";
+  }
+  PrintOMPExecutableDirective(Node);
+}
+
 void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
   Indent() << "#pragma omp parallel for ";
   PrintOMPExecutableDirective(Node);

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jul 21 04:42:05 2014
@@ -393,6 +393,11 @@ void StmtProfiler::VisitOMPMasterDirecti
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
+  VisitOMPExecutableDirective(S);
+  VisitName(S->getDirectiveName().getName());
+}
+
 void
 StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
   VisitOMPExecutableDirective(S);

Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Mon Jul 21 04:42:05 2014
@@ -257,6 +257,7 @@ bool clang::isAllowedClauseForDirective(
   case OMPD_threadprivate:
   case OMPD_section:
   case OMPD_master:
+  case OMPD_critical:
   case OMPD_taskyield:
   case OMPD_barrier:
   case OMPD_taskwait:

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Mon Jul 21 04:42:05 2014
@@ -197,6 +197,9 @@ void CodeGenFunction::EmitStmt(const Stm
   case Stmt::OMPMasterDirectiveClass:
     EmitOMPMasterDirective(cast<OMPMasterDirective>(*S));
     break;
+  case Stmt::OMPCriticalDirectiveClass:
+    EmitOMPCriticalDirective(cast<OMPCriticalDirective>(*S));
+    break;
   case Stmt::OMPParallelForDirectiveClass:
     EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S));
     break;

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Jul 21 04:42:05 2014
@@ -94,6 +94,10 @@ void CodeGenFunction::EmitOMPMasterDirec
   llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
 }
 
+void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &) {
+  llvm_unreachable("CodeGen for 'omp critical' is not supported yet.");
+}
+
 void
 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
   llvm_unreachable("CodeGen for 'omp parallel for' 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=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jul 21 04:42:05 2014
@@ -1928,6 +1928,7 @@ public:
   void EmitOMPSectionDirective(const OMPSectionDirective &S);
   void EmitOMPSingleDirective(const OMPSingleDirective &S);
   void EmitOMPMasterDirective(const OMPMasterDirective &S);
+  void EmitOMPCriticalDirective(const OMPCriticalDirective &S);
   void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
   void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
   void EmitOMPTaskDirective(const OMPTaskDirective &S);

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon Jul 21 04:42:05 2014
@@ -91,6 +91,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   case OMPD_section:
   case OMPD_single:
   case OMPD_master:
+  case OMPD_critical:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
     Diag(Tok, diag::err_omp_unexpected_directive)
@@ -109,9 +110,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
 ///
 ///       executable-directive:
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
-///         'section' | 'single' | 'master' | 'parallel for' |
-///         'parallel sections' | 'task' | 'taskyield' | 'barrier' | 'taskwait'
-///         {clause} annot_pragma_openmp_end
+///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
+///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
+///         'barrier' | 'taskwait' {clause} annot_pragma_openmp_end
 ///
 StmtResult
 Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
@@ -162,10 +163,26 @@ Parser::ParseOpenMPDeclarativeOrExecutab
   case OMPD_single:
   case OMPD_section:
   case OMPD_master:
+  case OMPD_critical:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
   case OMPD_task: {
     ConsumeToken();
+    // Parse directive name of the 'critical' directive if any.
+    if (DKind == OMPD_critical) {
+      BalancedDelimiterTracker T(*this, tok::l_paren,
+                                 tok::annot_pragma_openmp_end);
+      if (!T.consumeOpen()) {
+        if (Tok.isAnyIdentifier()) {
+          DirName =
+              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
+          ConsumeAnyToken();
+        } else {
+          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
+        }
+        T.consumeClose();
+      }
+    }
 
     if (isOpenMPLoopDirective(DKind))
       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
@@ -215,7 +232,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     }
     if (CreateDirective)
       Directive = Actions.ActOnOpenMPExecutableDirective(
-          DKind, Clauses, AssociatedStmt.get(), Loc, EndLoc);
+          DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
 
     // Exit scope.
     Actions.EndOpenMPDSABlock(Directive.get());

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jul 21 04:42:05 2014
@@ -155,6 +155,9 @@ public:
   DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
                              DirectivesPredicate DPred,
                              bool FromParent);
+  /// \brief Finds a directive which matches specified \a DPred predicate.
+  template <class NamedDirectivesPredicate>
+  bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
 
   /// \brief Returns currently analyzed directive.
   OpenMPDirectiveKind getCurrentDirective() const {
@@ -493,6 +496,20 @@ DSAStackTy::hasInnermostDSA(VarDecl *D,
   return DSAVarData();
 }
 
+template <class NamedDirectivesPredicate>
+bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
+  auto StartI = std::next(Stack.rbegin());
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  for (auto I = StartI, EE = EndI; I != EE; ++I) {
+    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
+      return true;
+  }
+  return false;
+}
+
 void Sema::InitDataSharingAttributesStack() {
   VarDataSharingAttributesStack = new DSAStackTy(*this);
 }
@@ -1008,6 +1025,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
                              Params);
     break;
   }
+  case OMPD_critical: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
   case OMPD_parallel_for: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
     QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
@@ -1067,9 +1092,10 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
   }
 }
 
-bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
-                           OpenMPDirectiveKind CurrentRegion,
-                           SourceLocation StartLoc) {
+static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+                                  OpenMPDirectiveKind CurrentRegion,
+                                  const DeclarationNameInfo &CurrentName,
+                                  SourceLocation StartLoc) {
   // Allowed nesting of constructs
   // +------------------+-----------------+------------------------------------+
   // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
@@ -1077,6 +1103,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | parallel         | parallel        | *                                  |
   // | parallel         | for             | *                                  |
   // | parallel         | master          | *                                  |
+  // | parallel         | critical        | *                                  |
   // | parallel         | simd            | *                                  |
   // | parallel         | sections        | *                                  |
   // | parallel         | section         | +                                  |
@@ -1091,6 +1118,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
   // | for              | master          | +                                  |
+  // | for              | critical        | *                                  |
   // | for              | simd            | *                                  |
   // | for              | sections        | +                                  |
   // | for              | section         | +                                  |
@@ -1105,6 +1133,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | master           | parallel        | *                                  |
   // | master           | for             | +                                  |
   // | master           | master          | *                                  |
+  // | master           | critical        | *                                  |
   // | master           | simd            | *                                  |
   // | master           | sections        | +                                  |
   // | master           | section         | +                                  |
@@ -1116,9 +1145,25 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | master           | barrier         | +                                  |
   // | master           | taskwait        | *                                  |
   // +------------------+-----------------+------------------------------------+
+  // | critical         | parallel        | *                                  |
+  // | critical         | for             | +                                  |
+  // | critical         | master          | *                                  |
+  // | critical         | critical        | * (should have dirrerent names)    |
+  // | critical         | simd            | *                                  |
+  // | critical         | sections        | +                                  |
+  // | critical         | section         | +                                  |
+  // | critical         | single          | +                                  |
+  // | critical         | parallel for    | *                                  |
+  // | critical         |parallel sections| *                                  |
+  // | critical         | task            | *                                  |
+  // | critical         | taskyield       | *                                  |
+  // | critical         | barrier         | +                                  |
+  // | critical         | taskwait        | *                                  |
+  // +------------------+-----------------+------------------------------------+
   // | simd             | parallel        |                                    |
   // | simd             | for             |                                    |
   // | simd             | master          |                                    |
+  // | simd             | critical        |                                    |
   // | simd             | simd            |                                    |
   // | simd             | sections        |                                    |
   // | simd             | section         |                                    |
@@ -1133,6 +1178,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
   // | sections         | master          | +                                  |
+  // | sections         | critical        | *                                  |
   // | sections         | simd            | *                                  |
   // | sections         | sections        | +                                  |
   // | sections         | section         | *                                  |
@@ -1147,6 +1193,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
   // | section          | master          | +                                  |
+  // | section          | critical        | *                                  |
   // | section          | simd            | *                                  |
   // | section          | sections        | +                                  |
   // | section          | section         | +                                  |
@@ -1161,6 +1208,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
   // | single           | master          | +                                  |
+  // | single           | critical        | *                                  |
   // | single           | simd            | *                                  |
   // | single           | sections        | +                                  |
   // | single           | section         | +                                  |
@@ -1175,6 +1223,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
   // | parallel for     | master          | +                                  |
+  // | parallel for     | critical        | *                                  |
   // | parallel for     | simd            | *                                  |
   // | parallel for     | sections        | +                                  |
   // | parallel for     | section         | +                                  |
@@ -1189,6 +1238,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | parallel sections| parallel        | *                                  |
   // | parallel sections| for             | +                                  |
   // | parallel sections| master          | +                                  |
+  // | parallel sections| critical        | +                                  |
   // | parallel sections| simd            | *                                  |
   // | parallel sections| sections        | +                                  |
   // | parallel sections| section         | *                                  |
@@ -1203,6 +1253,7 @@ bool CheckNestingOfRegions(Sema &SemaRef
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
   // | task             | master          | +                                  |
+  // | task             | critical        | *                                  |
   // | task             | simd            | *                                  |
   // | task             | sections        | +                                  |
   // | task             | section         | +                                  |
@@ -1245,14 +1296,44 @@ bool CheckNestingOfRegions(Sema &SemaRef
       // atomic (TODO), or explicit task region.
       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
                           ParentRegion == OMPD_task;
+    } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A critical region may not be nested (closely or otherwise) inside a
+      // critical region with the same name. Note that this restriction is not
+      // sufficient to prevent deadlock.
+      SourceLocation PreviousCriticalLoc;
+      bool DeadLock =
+          Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
+                                  OpenMPDirectiveKind K,
+                                  const DeclarationNameInfo &DNI,
+                                  SourceLocation Loc)
+                                  ->bool {
+                                if (K == OMPD_critical &&
+                                    DNI.getName() == CurrentName.getName()) {
+                                  PreviousCriticalLoc = Loc;
+                                  return true;
+                                } else
+                                  return false;
+                              },
+                              false /* skip top directive */);
+      if (DeadLock) {
+        SemaRef.Diag(StartLoc,
+                     diag::err_omp_prohibited_region_critical_same_name)
+            << CurrentName.getName();
+        if (PreviousCriticalLoc.isValid())
+          SemaRef.Diag(PreviousCriticalLoc,
+                       diag::note_omp_previous_critical_region);
+        return true;
+      }
     } 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(TODO), ordered(TODO), atomic(TODO), or master
+      // explicit task, critical, ordered(TODO), atomic(TODO), or master
       // region.
       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
                           ParentRegion == OMPD_task ||
-                          ParentRegion == OMPD_master;
+                          ParentRegion == OMPD_master ||
+                          ParentRegion == OMPD_critical;
     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
                !isOpenMPParallelDirective(CurrentRegion) &&
                !isOpenMPSimdDirective(CurrentRegion)) {
@@ -1263,7 +1344,8 @@ bool CheckNestingOfRegions(Sema &SemaRef
       NestingProhibited = (isOpenMPWorksharingDirective(ParentRegion) &&
                            !isOpenMPSimdDirective(ParentRegion)) ||
                           ParentRegion == OMPD_task ||
-                          ParentRegion == OMPD_master;
+                          ParentRegion == OMPD_master ||
+                          ParentRegion == OMPD_critical;
       ShouldBeInParallelRegion = true;
     }
     if (NestingProhibited) {
@@ -1277,12 +1359,13 @@ bool CheckNestingOfRegions(Sema &SemaRef
 }
 
 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                                const DeclarationNameInfo &DirName,
                                                 ArrayRef<OMPClause *> Clauses,
                                                 Stmt *AStmt,
                                                 SourceLocation StartLoc,
                                                 SourceLocation EndLoc) {
   StmtResult Res = StmtError();
-  if (CheckNestingOfRegions(*this, DSAStack, Kind, StartLoc))
+  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc))
     return StmtError();
 
   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
@@ -1343,6 +1426,11 @@ StmtResult Sema::ActOnOpenMPExecutableDi
            "No clauses are allowed for 'omp master' directive");
     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
     break;
+  case OMPD_critical:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp critical' directive");
+    Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc);
+    break;
   case OMPD_parallel_for:
     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
                                           EndLoc, VarsWithInheritedDSA);
@@ -2042,6 +2130,18 @@ StmtResult Sema::ActOnOpenMPMasterDirect
   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
 }
 
+StmtResult
+Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+                                   Stmt *AStmt, SourceLocation StartLoc,
+                                   SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
+                                      AStmt);
+}
+
 StmtResult Sema::ActOnOpenMPParallelForDirective(
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jul 21 04:42:05 2014
@@ -1298,12 +1298,12 @@ public:
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                           DeclarationNameInfo DirName,
                                            ArrayRef<OMPClause *> Clauses,
-                                           Stmt *AStmt,
-                                           SourceLocation StartLoc,
+                                           Stmt *AStmt, SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
-    return getSema().ActOnOpenMPExecutableDirective(Kind, Clauses, AStmt,
-                                                    StartLoc, EndLoc);
+    return getSema().ActOnOpenMPExecutableDirective(Kind, DirName, Clauses,
+                                                    AStmt, StartLoc, EndLoc);
   }
 
   /// \brief Build a new OpenMP 'if' clause.
@@ -6445,9 +6445,16 @@ StmtResult TreeTransform<Derived>::Trans
     return StmtError();
   }
 
+  // Transform directive name for 'omp critical' directive.
+  DeclarationNameInfo DirName;
+  if (D->getDirectiveKind() == OMPD_critical) {
+    DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
+    DirName = getDerived().TransformDeclarationNameInfo(DirName);
+  }
+
   return getDerived().RebuildOMPExecutableDirective(
-      D->getDirectiveKind(), TClauses, AssociatedStmt.get(), D->getLocStart(),
-      D->getLocEnd());
+      D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
+      D->getLocStart(), D->getLocEnd());
 }
 
 template <typename Derived>
@@ -6525,6 +6532,16 @@ TreeTransform<Derived>::TransformOMPMast
   StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
   getDerived().getSema().EndOpenMPDSABlock(Res.get());
   return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
+  getDerived().getSema().StartOpenMPDSABlock(
+      OMPD_critical, D->getDirectiveName(), nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
 }
 
 template <typename Derived>

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jul 21 04:42:05 2014
@@ -1968,6 +1968,12 @@ void ASTStmtReader::VisitOMPMasterDirect
   VisitOMPExecutableDirective(D);
 }
 
+void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  ReadDeclarationNameInfo(D->DirName, Record, Idx);
+}
+
 void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
   VisitStmt(D);
   // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
@@ -2521,6 +2527,10 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       S = OMPMasterDirective::CreateEmpty(Context, Empty);
       break;
 
+    case STMT_OMP_CRITICAL_DIRECTIVE:
+      S = OMPCriticalDirective::CreateEmpty(Context, Empty);
+      break;
+
     case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
       unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
       unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jul 21 04:42:05 2014
@@ -1868,6 +1868,13 @@ void ASTStmtWriter::VisitOMPMasterDirect
   Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record);
+  Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
+}
+
 void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
   VisitStmt(D);
   Record.push_back(D->getNumClauses());

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Jul 21 04:42:05 2014
@@ -738,6 +738,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
     case Stmt::OMPSectionDirectiveClass:
     case Stmt::OMPSingleDirectiveClass:
     case Stmt::OMPMasterDirectiveClass:
+    case Stmt::OMPCriticalDirectiveClass:
     case Stmt::OMPParallelForDirectiveClass:
     case Stmt::OMPParallelSectionsDirectiveClass:
     case Stmt::OMPTaskDirectiveClass:

Added: cfe/trunk/test/OpenMP/critical_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/critical_ast_print.cpp?rev=213510&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/critical_ast_print.cpp (added)
+++ cfe/trunk/test/OpenMP/critical_ast_print.cpp Mon Jul 21 04:42:05 2014
@@ -0,0 +1,29 @@
+// 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() {}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp critical
+  a=2;
+// CHECK-NEXT: #pragma omp critical
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: ++a;
+  ++a;
+#pragma omp critical  (the_name)
+  foo();
+// CHECK-NEXT: #pragma omp critical (the_name)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: return 0;
+  return 0;
+}
+
+#endif

Added: cfe/trunk/test/OpenMP/critical_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/critical_messages.cpp?rev=213510&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/critical_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/critical_messages.cpp Mon Jul 21 04:42:05 2014
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+int foo();
+
+int main() {
+  #pragma omp critical
+  ;
+  #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}}
+  #pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}}
+  #pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical (name // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical (name1)
+  foo();
+  {
+    #pragma omp critical
+  } // expected-error {{expected statement}}
+  #pragma omp critical (name) // expected-note {{previous 'critical' region starts here}}
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      foo();
+      #pragma omp critical(name) // expected-error {{cannot nest 'critical' regions having the same name 'name'}}
+      foo();
+    }
+  }
+  #pragma omp critical (name)
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      #pragma omp critical
+      foo();
+    }
+  }
+  #pragma omp critical (name)
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      #pragma omp critical (nam)
+      foo();
+    }
+  }
+
+  return 0;
+}
+
+int foo() {
+  L1:
+    foo();
+  #pragma omp critical
+  {
+    foo();
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+  #pragma omp critical
+  {
+    L2:
+    foo();
+  }
+
+  return 0;
+}

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=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)
+++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Mon Jul 21 04:42:05 2014
@@ -33,6 +33,11 @@ void foo() {
     bar();
   }
 #pragma omp parallel
+#pragma omp critical
+  {
+    bar();
+  }
+#pragma omp parallel
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
@@ -111,6 +116,13 @@ void foo() {
   }
 #pragma omp simd
   for (int i = 0; i < 10; ++i) {
+#pragma omp critical // 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 parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     for (int i = 0; i < 10; ++i)
       ;
@@ -193,7 +205,13 @@ void foo() {
       bar();
     }
   }
-
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical 
+    {
+      bar();
+    }
+  }
 #pragma omp for
   for (int i = 0; i < 10; ++i) {
 #pragma omp parallel
@@ -318,6 +336,25 @@ void foo() {
   }
 #pragma omp sections
   {
+#pragma omp parallel
+    {
+#pragma omp critical(A) // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp critical // OK
+      {
+        bar();
+      }
+    }
+#pragma omp critical(A) // expected-error {{statement in 'omp sections' directive must be enclosed into a section region}}
+    bar();
+  }
+#pragma omp sections
+  {
 #pragma omp parallel for
     for (int i = 0; i < 10; ++i)
       ;
@@ -409,6 +446,8 @@ void foo() {
       bar();
 #pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
       bar();
+#pragma omp critical
+      bar();
     }
   }
 #pragma omp sections
@@ -520,6 +559,13 @@ void foo() {
   }
 #pragma omp single
   {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
 #pragma omp sections // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
     {
       bar();
@@ -613,6 +659,13 @@ void foo() {
   }
 #pragma omp master
   {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
 #pragma omp sections // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
     {
       bar();
@@ -671,6 +724,125 @@ void foo() {
     bar();
   }
 
+// CRITICAL DIRECTIVE
+#pragma omp critical
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'critical' region}}
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp critical(Tuzik)
+  {
+#pragma omp critical(grelka)
+    bar();
+  }
+#pragma omp critical(Belka)// expected-note {{previous 'critical' region starts here}}
+  {
+#pragma omp critical(Belka) // expected-error {{cannot nest 'critical' regions having the same name 'Belka'}}
+    {
+#pragma omp critical(Tuzik)
+      {
+#pragma omp parallel
+#pragma omp critical(grelka)
+        {
+          bar();
+        }
+      }
+    }
+  }
+
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -722,6 +894,14 @@ void foo() {
 
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
 #pragma omp parallel
     {
 #pragma omp single // OK
@@ -824,6 +1004,14 @@ void foo() {
   }
 #pragma omp parallel sections
   {
+#pragma omp section
+    {
+#pragma omp critical
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
 #pragma omp parallel
     {
 #pragma omp single // OK
@@ -898,6 +1086,10 @@ void foo() {
 #pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
   bar();
 #pragma omp task
+#pragma omp critical
+  bar();
+
+#pragma omp task
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
@@ -960,6 +1152,9 @@ void foo() {
 #pragma omp master
   bar();
 #pragma omp parallel
+#pragma omp critical
+  bar();
+#pragma omp parallel
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
@@ -1031,6 +1226,13 @@ void foo() {
   }
 #pragma omp simd
   for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+#pragma omp critical // 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 parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
     for (int i = 0; i < 10; ++i)
       ;
@@ -1104,6 +1306,8 @@ void foo() {
     bar();
 #pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
     bar();
+#pragma omp critical
+    bar();
   }
 #pragma omp for
   for (int i = 0; i < 10; ++i) {
@@ -1193,6 +1397,8 @@ void foo() {
   }
 #pragma omp sections
   {
+#pragma omp critical
+    bar();
 #pragma omp single // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
     bar();
 #pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
@@ -1309,6 +1515,8 @@ void foo() {
       bar();
 #pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
       bar();
+#pragma omp critical
+      bar();
     }
   }
 #pragma omp sections
@@ -1412,6 +1620,8 @@ void foo() {
     }
 #pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
     bar();
+#pragma omp critical
+    bar();
   }
 #pragma omp single
   {
@@ -1508,6 +1718,13 @@ void foo() {
   }
 #pragma omp master
   {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
 #pragma omp sections // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
     {
       bar();
@@ -1566,6 +1783,125 @@ void foo() {
     bar();
   }
 
+// CRITICAL DIRECTIVE
+#pragma omp critical
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'critical' region}}
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp critical(Belka)
+  {
+#pragma omp critical(Strelka)
+    bar();
+  }
+#pragma omp critical(Tuzik)// expected-note {{previous 'critical' region starts here}}
+  {
+#pragma omp critical(grelka) // expected-note {{previous 'critical' region starts here}}
+    {
+#pragma omp critical(Tuzik) // expected-error {{cannot nest 'critical' regions having the same name 'Tuzik'}}
+      {
+#pragma omp parallel
+#pragma omp critical(grelka) // expected-error {{cannot nest 'critical' regions having the same name 'grelka'}}
+        {
+          bar();
+        }
+      }
+    }
+  }
+
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -1609,6 +1945,10 @@ void foo() {
     {
       bar();
     }
+#pragma omp critical
+    {
+      bar();
+    }
   }
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -1622,6 +1962,10 @@ void foo() {
       {
         bar();
       }
+#pragma omp critical // OK
+      {
+        bar();
+      }
 #pragma omp for // OK
       for (int i = 0; i < 10; ++i)
         ;
@@ -1708,6 +2052,8 @@ void foo() {
       bar();
 #pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
       bar();
+#pragma omp critical
+      bar();
     }
   }
 #pragma omp parallel sections
@@ -1722,6 +2068,10 @@ void foo() {
       {
         bar();
       }
+#pragma omp critical // OK
+      {
+        bar();
+      }
 #pragma omp for // OK
       for (int i = 0; i < 10; ++i)
         ;
@@ -1790,6 +2140,9 @@ void foo() {
 #pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
   bar();
 #pragma omp task
+#pragma omp critical
+  bar();
+#pragma omp task
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jul 21 04:42:05 2014
@@ -1784,6 +1784,8 @@ public:
       return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
     case Stmt::DependentScopeDeclRefExprClass:
       return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
+    case Stmt::OMPCriticalDirectiveClass:
+      return cast<OMPCriticalDirective>(S)->getDirectiveName();
     }
   }
 };
@@ -1861,6 +1863,7 @@ public:
   void VisitOMPSectionDirective(const OMPSectionDirective *D);
   void VisitOMPSingleDirective(const OMPSingleDirective *D);
   void VisitOMPMasterDirective(const OMPMasterDirective *D);
+  void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
   void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
   void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
   void VisitOMPTaskDirective(const OMPTaskDirective *D);
@@ -2330,6 +2333,11 @@ void EnqueueVisitor::VisitOMPMasterDirec
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
+  VisitOMPExecutableDirective(D);
+  AddDeclarationNameInfo(D);
+}
+
 void
 EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
   VisitOMPExecutableDirective(D);
@@ -4043,6 +4051,8 @@ CXString clang_getCursorKindSpelling(enu
     return cxstring::createRef("OMPSingleDirective");
   case CXCursor_OMPMasterDirective:
     return cxstring::createRef("OMPMasterDirective");
+  case CXCursor_OMPCriticalDirective:
+    return cxstring::createRef("OMPCriticalDirective");
   case CXCursor_OMPParallelForDirective:
     return cxstring::createRef("OMPParallelForDirective");
   case CXCursor_OMPParallelSectionsDirective:

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213510&r1=213509&r2=213510&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Jul 21 04:42:05 2014
@@ -538,6 +538,9 @@ CXCursor cxcursor::MakeCXCursor(const St
   case Stmt::OMPMasterDirectiveClass:
     K = CXCursor_OMPMasterDirective;
     break;
+  case Stmt::OMPCriticalDirectiveClass:
+    K = CXCursor_OMPCriticalDirective;
+    break;
   case Stmt::OMPParallelForDirectiveClass:
     K = CXCursor_OMPParallelForDirective;
     break;





More information about the cfe-commits mailing list