]> granicus.if.org Git - clang/commitdiff
[OPENMP] Parsing/Sema analysis of directive 'master'
authorAlexander Musman <alexander.musman@gmail.com>
Thu, 17 Jul 2014 08:54:58 +0000 (08:54 +0000)
committerAlexander Musman <alexander.musman@gmail.com>
Thu, 17 Jul 2014 08:54:58 +0000 (08:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213237 91177308-0d34-0410-b5e6-96231b3b80d8

26 files changed:
include/clang-c/Index.h
include/clang/AST/DataRecursiveASTVisitor.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/AST/StmtOpenMP.h
include/clang/Basic/OpenMPKinds.def
include/clang/Basic/StmtNodes.td
include/clang/Sema/Sema.h
include/clang/Serialization/ASTBitCodes.h
lib/AST/Stmt.cpp
lib/AST/StmtPrinter.cpp
lib/AST/StmtProfile.cpp
lib/Basic/OpenMPKinds.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CGStmtOpenMP.cpp
lib/CodeGen/CodeGenFunction.h
lib/Parse/ParseOpenMP.cpp
lib/Sema/SemaOpenMP.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/OpenMP/master_ast_print.cpp [new file with mode: 0644]
test/OpenMP/master_messages.cpp [new file with mode: 0644]
test/OpenMP/nesting_of_regions.cpp
tools/libclang/CIndex.cpp
tools/libclang/CXCursor.cpp

index 7f3f248266785949d553c1c4815921a839ce6cd1..c514fb03b515466cd5f4d89ff0b7f0c859012c39 100644 (file)
@@ -2167,9 +2167,13 @@ enum CXCursorKind {
    */
   CXCursor_OMPTaskDirective              = 240,
 
+  /** \brief OpenMP master directive.
+   */
+  CXCursor_OMPMasterDirective            = 241,
+
   /** \brief Windows Structured Exception Handling's leave statement.
    */
-  CXCursor_SEHLeaveStmt                  = 241,
+  CXCursor_SEHLeaveStmt                  = 242,
 
   CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
 
index 70bf06b5131756b1d1fa79939cf50a5ddb2ae857..e47e99b496d344448dc3fa0b8bcb6e99677ed5ee 100644 (file)
@@ -2297,6 +2297,9 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
 DEF_TRAVERSE_STMT(OMPSingleDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 DEF_TRAVERSE_STMT(OMPParallelForDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
index 833cfbe6f9df3503254fec5b2cbff25833f1e697..208d0f509d89ec2022825854711c60dd291733e5 100644 (file)
@@ -2319,6 +2319,9 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
 DEF_TRAVERSE_STMT(OMPSingleDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 DEF_TRAVERSE_STMT(OMPParallelForDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
index e74febea9c2a90afb9778e96b7b13390859c42e9..1c0978594243d9d6cfdc05691b39e9a1a55bcda1 100644 (file)
@@ -527,6 +527,53 @@ public:
   }
 };
 
+/// \brief This represents '#pragma omp master' directive.
+///
+/// \code
+/// #pragma omp master
+/// \endcode
+///
+class OMPMasterDirective : 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.
+  ///
+  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPMasterDirective()
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               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 OMPMasterDirective *Create(const ASTContext &C,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc,
+                                    Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPMasterDirectiveClass;
+  }
+};
+
 /// \brief This represents '#pragma omp parallel for' directive.
 ///
 /// \code
index ff08b1432a9380df07850fd80e16d146358644ab..61d23d4658617392fdcb205dd730df60d4abb72d 100644 (file)
@@ -64,6 +64,7 @@ OPENMP_DIRECTIVE(for)
 OPENMP_DIRECTIVE(sections)
 OPENMP_DIRECTIVE(section)
 OPENMP_DIRECTIVE(single)
+OPENMP_DIRECTIVE(master)
 OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
 OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
 
index 71b5629811a1d2622933aca1b558047cd73cd17e..9d56783c7ad16f9171b5ac4e53e161abefbc10d4 100644 (file)
@@ -184,6 +184,7 @@ def OMPForDirective : DStmt<OMPExecutableDirective>;
 def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
 def OMPSectionDirective : DStmt<OMPExecutableDirective>;
 def OMPSingleDirective : DStmt<OMPExecutableDirective>;
+def OMPMasterDirective : DStmt<OMPExecutableDirective>;
 def OMPParallelForDirective : DStmt<OMPExecutableDirective>;
 def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
 def OMPTaskDirective : DStmt<OMPExecutableDirective>;
index bb8887a82a20c58d2f4ebfb2bf3c3d143bdabcf0..f6479208887c2771ed2551a64da74af1399b986c 100644 (file)
@@ -7347,6 +7347,10 @@ public:
   StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
                                         Stmt *AStmt, SourceLocation StartLoc,
                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
   /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
   /// of the  associated statement.
   StmtResult ActOnOpenMPParallelForDirective(
index 1b1cd0a66b62572421ae462f787ac1a46a8069bb..d1d32ac8e793a9693faa002fcb61470cc95869eb 100644 (file)
@@ -1346,6 +1346,7 @@ namespace clang {
       STMT_OMP_SECTIONS_DIRECTIVE,
       STMT_OMP_SECTION_DIRECTIVE,
       STMT_OMP_SINGLE_DIRECTIVE,
+      STMT_OMP_MASTER_DIRECTIVE,
       STMT_OMP_PARALLEL_FOR_DIRECTIVE,
       STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
       STMT_OMP_TASK_DIRECTIVE,
index b415e9201e5fcaa48eb734a10d84ce9533d64b53..9185e4870e05d23ecf6e8ecfc64840c3dd11b7af 100644 (file)
@@ -1478,6 +1478,26 @@ OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
   return new (Mem) OMPSingleDirective(NumClauses);
 }
 
+OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C,
+                                               SourceLocation StartLoc,
+                                               SourceLocation EndLoc,
+                                               Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C,
+                                                    EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPMasterDirective();
+}
+
 OMPParallelForDirective *
 OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation EndLoc, unsigned CollapsedNum,
index 5958dacf3a8729e1bd218b01c1541b4f542a9e08..fd511ef465def461139b4e2abc270aa8794639c6 100644 (file)
@@ -821,6 +821,11 @@ void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
+  Indent() << "#pragma omp master";
+  PrintOMPExecutableDirective(Node);
+}
+
 void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
   Indent() << "#pragma omp parallel for ";
   PrintOMPExecutableDirective(Node);
index d0c39a5f340931accda0f99046adc04ab3acc06e..c45281f13f4a91fd0635d0896c705ff600b0f53a 100644 (file)
@@ -385,6 +385,10 @@ void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
 void
 StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
   VisitOMPExecutableDirective(S);
index 056d3587074cb0101b6683198ca54aa215bda25a..31b571cac8c34fe53ce2a1cb1910e37f09643155 100644 (file)
@@ -252,6 +252,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
   case OMPD_unknown:
   case OMPD_threadprivate:
   case OMPD_section:
+  case OMPD_master:
     break;
   }
   return false;
index 39adf9b71302cc7d8d6c5abfc79350a8aa242bfc..788fd067be50b24774a29a236ff90852a525cc19 100644 (file)
@@ -194,6 +194,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
   case Stmt::OMPSingleDirectiveClass:
     EmitOMPSingleDirective(cast<OMPSingleDirective>(*S));
     break;
+  case Stmt::OMPMasterDirectiveClass:
+    EmitOMPMasterDirective(cast<OMPMasterDirective>(*S));
+    break;
   case Stmt::OMPParallelForDirectiveClass:
     EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S));
     break;
index 3d36dbb1b1a7d0633477c8c19355a0d6fa797318..f086146724605ecc39234b3d4e9997863c3c755e 100644 (file)
@@ -90,6 +90,10 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
   llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
 }
 
+void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
+  llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
+}
+
 void
 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
   llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
index f6dd39f8fbddd061eb16226e655321a3027e0714..d6675f39c7d31f4e4a2b133f543fbe17eb9e21a8 100644 (file)
@@ -1916,6 +1916,7 @@ public:
   void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
   void EmitOMPSectionDirective(const OMPSectionDirective &S);
   void EmitOMPSingleDirective(const OMPSingleDirective &S);
+  void EmitOMPMasterDirective(const OMPMasterDirective &S);
   void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
   void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
   void EmitOMPTaskDirective(const OMPTaskDirective &S);
index e50f4714e49297a925d8a6a90c5f8820dea455b8..172aef8cf3e206e59ae0edf82167db90262e11d4 100644 (file)
@@ -87,6 +87,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
   case OMPD_sections:
   case OMPD_section:
   case OMPD_single:
+  case OMPD_master:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
     Diag(Tok, diag::err_omp_unexpected_directive)
@@ -105,8 +106,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
 ///
 ///       executable-directive:
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
-///         'section' | 'single' | 'parallel for' | 'parallel sections' | 'task'
-///         {clause} annot_pragma_openmp_end
+///         'section' | 'single' | 'master' | 'parallel for' |
+///         'parallel sections' | 'task' {clause} annot_pragma_openmp_end
 ///
 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
@@ -146,6 +147,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
   case OMPD_sections:
   case OMPD_single:
   case OMPD_section:
+  case OMPD_master:
   case OMPD_parallel_for:
   case OMPD_parallel_sections:
   case OMPD_task: {
index 58f9bbed6f9c10a239b968615c9d2fe0a961e742..ef36e7e901e83cc14c3ee37073825f6bdd2fd9b2 100644 (file)
@@ -1000,6 +1000,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
                              Params);
     break;
   }
+  case OMPD_master: {
+    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);
@@ -1044,9 +1052,10 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | parallel         | parallel        | *                                  |
   // | parallel         | for             | *                                  |
+  // | parallel         | master          | *                                  |
   // | parallel         | simd            | *                                  |
   // | parallel         | sections        | *                                  |
-  // | parallel         | section         | +                                  | 
+  // | parallel         | section         | +                                  |
   // | parallel         | single          | *                                  |
   // | parallel         | parallel for    | *                                  |
   // | parallel         |parallel sections| *                                  |
@@ -1054,6 +1063,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
+  // | for              | master          | +                                  |
   // | for              | simd            | *                                  |
   // | for              | sections        | +                                  |
   // | for              | section         | +                                  |
@@ -1062,8 +1072,20 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // | for              |parallel sections| *                                  |
   // | for              | task            | *                                  |
   // +------------------+-----------------+------------------------------------+
+  // | master           | parallel        | *                                  |
+  // | master           | for             | +                                  |
+  // | master           | master          | *                                  |
+  // | master           | simd            | *                                  |
+  // | master           | sections        | +                                  |
+  // | master           | section         | +                                  |
+  // | master           | single          | +                                  |
+  // | master           | parallel for    | *                                  |
+  // | master           |parallel sections| *                                  |
+  // | master           | task            | *                                  |
+  // +------------------+-----------------+------------------------------------+
   // | simd             | parallel        |                                    |
   // | simd             | for             |                                    |
+  // | simd             | master          |                                    |
   // | simd             | simd            |                                    |
   // | simd             | sections        |                                    |
   // | simd             | section         |                                    |
@@ -1074,6 +1096,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
+  // | sections         | master          | +                                  |
   // | sections         | simd            | *                                  |
   // | sections         | sections        | +                                  |
   // | sections         | section         | *                                  |
@@ -1084,6 +1107,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
+  // | section          | master          | +                                  |
   // | section          | simd            | *                                  |
   // | section          | sections        | +                                  |
   // | section          | section         | +                                  |
@@ -1094,6 +1118,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
+  // | single           | master          | +                                  |
   // | single           | simd            | *                                  |
   // | single           | sections        | +                                  |
   // | single           | section         | +                                  |
@@ -1104,6 +1129,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
+  // | parallel for     | master          | +                                  |
   // | parallel for     | simd            | *                                  |
   // | parallel for     | sections        | +                                  |
   // | parallel for     | section         | +                                  |
@@ -1114,6 +1140,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | parallel sections| parallel        | *                                  |
   // | parallel sections| for             | +                                  |
+  // | parallel sections| master          | +                                  |
   // | parallel sections| simd            | *                                  |
   // | parallel sections| sections        | +                                  |
   // | parallel sections| section         | *                                  |
@@ -1124,9 +1151,10 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
   // +------------------+-----------------+------------------------------------+
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
+  // | task             | master          | +                                  |
   // | task             | simd            | *                                  |
   // | task             | sections        | +                                  |
-  // | task             | section         | +                                  | 
+  // | task             | section         | +                                  |
   // | task             | single          | +                                  |
   // | task             | parallel for    | *                                  |
   // | task             |parallel sections| *                                  |
@@ -1157,16 +1185,23 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
       }
       return false;
     }
-    if (isOpenMPWorksharingDirective(CurrentRegion) &&
-        !isOpenMPParallelDirective(CurrentRegion) &&
-        !isOpenMPSimdDirective(CurrentRegion)) {
+    if (CurrentRegion == OMPD_master) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A master region may not be closely nested inside a worksharing,
+      // atomic (TODO), or explicit task region.
+      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
+                          ParentRegion == OMPD_task;
+    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
+               !isOpenMPParallelDirective(CurrentRegion) &&
+               !isOpenMPSimdDirective(CurrentRegion)) {
       // OpenMP [2.16, Nesting of Regions]
       // 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)) ||
-                          ParentRegion == OMPD_task;
+                          ParentRegion == OMPD_task ||
+                          ParentRegion == OMPD_master;
       ShouldBeInParallelRegion = true;
     }
     if (NestingProhibited) {
@@ -1231,13 +1266,18 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
     break;
   case OMPD_section:
     assert(ClausesWithImplicit.empty() &&
-           "No clauses is allowed for 'omp section' directive");
+           "No clauses are allowed for 'omp section' directive");
     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
     break;
   case OMPD_single:
     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
                                      EndLoc);
     break;
+  case OMPD_master:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp master' directive");
+    Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
+    break;
   case OMPD_parallel_for:
     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
                                           EndLoc, VarsWithInheritedDSA);
@@ -1906,6 +1946,16 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
 }
 
+StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
+                                            SourceLocation StartLoc,
+                                            SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
 StmtResult Sema::ActOnOpenMPParallelForDirective(
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
index f9775c1ad101ef7e13781bacec1b08d35afe5505..6eb18e8ac792d319959f16f17e2cdc7f3b5250e3 100644 (file)
@@ -6508,6 +6508,17 @@ TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
   return Res;
 }
 
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
 template <typename Derived>
 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
     OMPParallelForDirective *D) {
index e719bbb5140f08ab7003575d60d9244b1e369c3f..e6c71b45a1bef5d59d21b02d0dca4fae388f747a 100644 (file)
@@ -1952,6 +1952,11 @@ void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
   VisitOMPExecutableDirective(D);
 }
 
+void ASTStmtReader::VisitOMPMasterDirective(OMPMasterDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
 void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
   VisitStmt(D);
   // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
@@ -2486,6 +2491,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           Context, Record[ASTStmtReader::NumStmtFields], Empty);
       break;
 
+    case STMT_OMP_MASTER_DIRECTIVE:
+      S = OMPMasterDirective::CreateEmpty(Context, Empty);
+      break;
+
     case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
       unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
       unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
index cacb2ec1852de20d6b8a5ef6626a16439cee1c04..e8027e733c104f154dc785d67106feb78813263f 100644 (file)
@@ -1857,6 +1857,12 @@ void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
   Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
+}
+
 void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
   VisitStmt(D);
   Record.push_back(D->getNumClauses());
index dec4d46b15384fa1528a5fa4f3e9efa7a5f3ce50..58b33573bf57c440049ba007a135d028dc2c730c 100644 (file)
@@ -737,6 +737,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
     case Stmt::OMPSectionsDirectiveClass:
     case Stmt::OMPSectionDirectiveClass:
     case Stmt::OMPSingleDirectiveClass:
+    case Stmt::OMPMasterDirectiveClass:
     case Stmt::OMPParallelForDirectiveClass:
     case Stmt::OMPParallelSectionsDirectiveClass:
     case Stmt::OMPTaskDirectiveClass:
diff --git a/test/OpenMP/master_ast_print.cpp b/test/OpenMP/master_ast_print.cpp
new file mode 100644 (file)
index 0000000..7ce4c10
--- /dev/null
@@ -0,0 +1,32 @@
+// 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 parallel
+{
+#pragma omp master
+{
+  a=2;
+}
+}
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: {
+// CHECK-NEXT: #pragma omp master
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/master_messages.cpp b/test/OpenMP/master_messages.cpp
new file mode 100644 (file)
index 0000000..fbe35ac
--- /dev/null
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+int foo();
+
+int main() {
+  #pragma omp master
+  ;
+  #pragma omp master nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp master'}}
+  #pragma omp master unknown // expected-warning {{extra tokens at the end of '#pragma omp master' are ignored}}
+  foo();
+  {
+    #pragma omp master
+  } // expected-error {{expected statement}}
+  #pragma omp for
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+    foo();
+  }
+  #pragma omp sections
+  {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
+    foo();
+  }
+  #pragma omp single
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    foo();
+  }
+  #pragma omp master
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master
+    foo();
+  }
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i)
+  #pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+  {
+    foo();
+  }
+
+  return 0;
+}
+
+int foo() {
+  L1:
+    foo();
+  #pragma omp master
+  {
+    foo();
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+  #pragma omp master
+  {
+    L2:
+    foo();
+  }
+
+  return 0;
+}
index c2e252673f1dc05866e6d48853bdd4ead7f25d4a..d61ac3f11b37bfbe0b90696d896b6c012ae44bd0 100644 (file)
@@ -26,6 +26,12 @@ void foo() {
 #pragma omp parallel
 #pragma omp single
   bar();
+
+#pragma omp parallel
+#pragma omp master
+  {
+    bar();
+  }
 #pragma omp parallel
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
@@ -83,6 +89,13 @@ void foo() {
   }
 #pragma omp simd
   for (int i = 0; i < 10; ++i) {
+#pragma omp master // 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)
       ;
@@ -142,6 +155,15 @@ void foo() {
       bar();
     }
   }
+
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+    {
+      bar();
+    }
+  }
+
 #pragma omp for
   for (int i = 0; i < 10; ++i) {
 #pragma omp parallel
@@ -232,6 +254,25 @@ void foo() {
   }
 #pragma omp sections
   {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp master // OK
+      {
+        bar();
+      }
+    }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
+    bar();
+  }
+#pragma omp sections
+  {
 #pragma omp parallel for
     for (int i = 0; i < 10; ++i)
       ;
@@ -309,6 +350,8 @@ void foo() {
     {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'section' 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 'section' region}}
+      bar();
     }
   }
 #pragma omp sections
@@ -389,6 +432,13 @@ void foo() {
   }
 #pragma omp single
   {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    {
+      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();
@@ -432,6 +482,84 @@ void foo() {
     }
   }
 
+// MASTER DIRECTIVE
+#pragma omp master
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      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();
+    }
+  }
+#pragma omp master
+  {
+#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 master
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -472,6 +600,15 @@ void foo() {
       bar();
     }
   }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    {
+      bar();
+    }
+  }
+
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
 #pragma omp parallel
@@ -553,6 +690,14 @@ void foo() {
   }
 #pragma omp parallel sections
   {
+#pragma omp section
+    {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
 #pragma omp parallel
     {
 #pragma omp single // OK
@@ -612,6 +757,9 @@ void foo() {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
   bar();
 #pragma omp task
+#pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
+  bar();
+#pragma omp task
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
@@ -625,6 +773,7 @@ void foo() {
   {
     bar();
   }
+
 }
 
 void foo() {
@@ -656,6 +805,9 @@ void foo() {
 #pragma omp single
   bar();
 #pragma omp parallel
+#pragma omp master
+  bar();
+#pragma omp parallel
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
@@ -707,6 +859,8 @@ void foo() {
   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 master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
   }
 #pragma omp simd
   for (int i = 0; i < 10; ++i) {
@@ -766,6 +920,8 @@ void foo() {
   for (int i = 0; i < 10; ++i) {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'for' 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 'for' region}}
+    bar();
   }
 #pragma omp for
   for (int i = 0; i < 10; ++i) {
@@ -842,6 +998,8 @@ void foo() {
   {
 #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}}
+    bar();
   }
 #pragma omp sections
   {
@@ -939,6 +1097,8 @@ void foo() {
     {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'section' 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 'section' region}}
+      bar();
     }
   }
 #pragma omp sections
@@ -1016,6 +1176,8 @@ void foo() {
     {
       bar();
     }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    bar();
   }
 #pragma omp single
   {
@@ -1062,6 +1224,84 @@ void foo() {
     }
   }
 
+// MASTER DIRECTIVE
+#pragma omp master
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      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();
+    }
+  }
+#pragma omp master
+  {
+#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 master
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -1101,6 +1341,10 @@ void foo() {
     {
       bar();
     }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    {
+      bar();
+    }
   }
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i) {
@@ -1110,6 +1354,10 @@ void foo() {
       {
         bar();
       }
+#pragma omp master // OK
+      {
+        bar();
+      }
 #pragma omp for // OK
       for (int i = 0; i < 10; ++i)
         ;
@@ -1179,6 +1427,8 @@ void foo() {
     {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'section' 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 'section' region}}
+      bar();
     }
   }
 #pragma omp parallel sections
@@ -1189,6 +1439,10 @@ void foo() {
       {
         bar();
       }
+#pragma omp master // OK
+      {
+        bar();
+      }
 #pragma omp for // OK
       for (int i = 0; i < 10; ++i)
         ;
@@ -1242,6 +1496,9 @@ void foo() {
 #pragma omp single // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
   bar();
 #pragma omp task
+#pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
+  bar();
+#pragma omp task
 #pragma omp parallel for
   for (int i = 0; i < 10; ++i)
     ;
index 4502017158e07138a29928494091475a3ae8e0ee..75438e20ea65c4f9b4554c7c2b86b82e81375ccb 100644 (file)
@@ -1860,6 +1860,7 @@ public:
   void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
   void VisitOMPSectionDirective(const OMPSectionDirective *D);
   void VisitOMPSingleDirective(const OMPSingleDirective *D);
+  void VisitOMPMasterDirective(const OMPMasterDirective *D);
   void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
   void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
   void VisitOMPTaskDirective(const OMPTaskDirective *D);
@@ -2318,6 +2319,10 @@ void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
 void
 EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
   VisitOMPExecutableDirective(D);
@@ -4016,6 +4021,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
     return cxstring::createRef("OMPSectionDirective");
   case CXCursor_OMPSingleDirective:
     return cxstring::createRef("OMPSingleDirective");
+  case CXCursor_OMPMasterDirective:
+    return cxstring::createRef("OMPMasterDirective");
   case CXCursor_OMPParallelForDirective:
     return cxstring::createRef("OMPParallelForDirective");
   case CXCursor_OMPParallelSectionsDirective:
index 6875f5abdc40a249590866783ec49ad26431ac56..e50a156a4011b205872267092a3931c08fc24ae5 100644 (file)
@@ -535,6 +535,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
   case Stmt::OMPSingleDirectiveClass:
     K = CXCursor_OMPSingleDirective;
     break;
+  case Stmt::OMPMasterDirectiveClass:
+    K = CXCursor_OMPMasterDirective;
+    break;
   case Stmt::OMPParallelForDirectiveClass:
     K = CXCursor_OMPParallelForDirective;
     break;