r246747 - [OPENMP 4.1] Parsing/sema analysis for extended format of 'if' clause.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 3 00:23:49 PDT 2015


Author: abataev
Date: Thu Sep  3 02:23:48 2015
New Revision: 246747

URL: http://llvm.org/viewvc/llvm-project?rev=246747&view=rev
Log:
[OPENMP 4.1] Parsing/sema analysis for extended format of 'if' clause.
OpenMP 4.1 added special 'directive-name-modifier' to the 'if' clause.
Format of 'if' clause is as follows:
```
if([ directive-name-modifier :] scalar-logical-expression)
```

The restriction rules are also changed.
1. If any 'if' clause on the directive includes a 'directive-name-modifier' then all 'if' clauses on the directive must include a 'directive-name-modifier'.
2. At most one 'if' clause without a 'directive-name-modifier' can appear on the directive.
3. At most one 'if' clause with some particular 'directive-name-modifier' can appear on the directive.

'directive-name-modifier' is important for combined directives and allows to separate conditions in 'if' clause for simple sub-directives in combined directive. This 'directive-name-modifier' identifies the sub-directive to which this 'if' clause must be applied.


Modified:
    cfe/trunk/include/clang/AST/OpenMPClause.h
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/StmtPrinter.cpp
    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/test/OpenMP/for_schedule_messages.cpp
    cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_if_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_simd_if_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp
    cfe/trunk/test/OpenMP/parallel_if_messages.cpp
    cfe/trunk/test/OpenMP/parallel_sections_if_messages.cpp
    cfe/trunk/test/OpenMP/target_data_if_messages.cpp
    cfe/trunk/test/OpenMP/target_if_messages.cpp
    cfe/trunk/test/OpenMP/task_if_messages.cpp

Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Thu Sep  3 02:23:48 2015
@@ -152,10 +152,10 @@ public:
 /// \brief This represents 'if' clause in the '#pragma omp ...' directive.
 ///
 /// \code
-/// #pragma omp parallel if(a > 5)
+/// #pragma omp parallel if(parallel:a > 5)
 /// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'if'
-/// clause with condition 'a > 5'.
+/// In this example directive '#pragma omp parallel' has simple 'if' clause with
+/// condition 'a > 5' and directive name modifier 'parallel'.
 ///
 class OMPIfClause : public OMPClause {
   friend class OMPClauseReader;
@@ -163,37 +163,67 @@ class OMPIfClause : public OMPClause {
   SourceLocation LParenLoc;
   /// \brief Condition of the 'if' clause.
   Stmt *Condition;
+  /// \brief Location of ':' (if any).
+  SourceLocation ColonLoc;
+  /// \brief Directive name modifier for the clause.
+  OpenMPDirectiveKind NameModifier;
+  /// \brief Name modifier location.
+  SourceLocation NameModifierLoc;
 
   /// \brief Set condition.
   ///
   void setCondition(Expr *Cond) { Condition = Cond; }
+  /// \brief Set directive name modifier for the clause.
+  ///
+  void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
+  /// \brief Set location of directive name modifier for the clause.
+  ///
+  void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
+  /// \brief Set location of ':'.
+  ///
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
 
 public:
   /// \brief Build 'if' clause with condition \a Cond.
   ///
+  /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
+  /// \param Cond Condition of the clause.
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
-  /// \param Cond Condition of the clause.
+  /// \param NameModifierLoc Location of directive name modifier.
+  /// \param ColonLoc [OpenMP 4.1] Location of ':'.
   /// \param EndLoc Ending location of the clause.
   ///
-  OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+  OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
+              SourceLocation StartLoc, SourceLocation LParenLoc,
+              SourceLocation NameModifierLoc, SourceLocation ColonLoc,
               SourceLocation EndLoc)
       : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
-        Condition(Cond) {}
+        Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
+        NameModifierLoc(NameModifierLoc) {}
 
   /// \brief Build an empty clause.
   ///
   OMPIfClause()
-      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
-        LParenLoc(SourceLocation()), Condition(nullptr) {}
+      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
+        Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
+        NameModifierLoc() {}
 
   /// \brief Sets the location of '('.
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
   /// \brief Returns the location of '('.
   SourceLocation getLParenLoc() const { return LParenLoc; }
 
+  /// \brief Return the location of ':'.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
   /// \brief Returns condition.
   Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+  /// \brief Return directive name modifier associated with the clause.
+  OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
+
+  /// \brief Return the location of directive name modifier.
+  SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
 
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_if;

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Sep  3 02:23:48 2015
@@ -211,4 +211,7 @@ def note_mt_message : Note<"[rewriter] %
 def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
 def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
 
+// OpenMP
+def err_omp_more_one_clause : Error<
+  "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier}2">;
 }

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Thu Sep  3 02:23:48 2015
@@ -987,8 +987,6 @@ def err_omp_expected_punc : Error<
   "expected ',' or ')' in '%0' %select{clause|directive}1">;
 def err_omp_unexpected_clause : Error<
   "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
-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<

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep  3 02:23:48 2015
@@ -7694,6 +7694,14 @@ def err_omp_wrong_linear_modifier_non_re
   "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">;
 def err_omp_wrong_simdlen_safelen_values : Error<
   "the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">;
+def err_omp_wrong_if_directive_name_modifier : Error<
+  "directive name modifier '%0' is not allowed for '#pragma omp %1'">;
+def err_omp_no_more_if_clause : Error<
+  "no more 'if' clause is allowed">;
+def err_omp_unnamed_if_clause : Error<
+  "expected %select{|one of}0 %1 directive name modifier%select{|s}0">;
+def note_omp_previous_named_if_clause : Note<
+  "previous clause with directive name modifier specified here">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep  3 02:23:48 2015
@@ -7889,8 +7889,11 @@ public:
                                          SourceLocation LParenLoc,
                                          SourceLocation EndLoc);
   /// \brief Called on well-formed 'if' clause.
-  OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+  OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
+                                 Expr *Condition, SourceLocation StartLoc,
                                  SourceLocation LParenLoc,
+                                 SourceLocation NameModifierLoc,
+                                 SourceLocation ColonLoc,
                                  SourceLocation EndLoc);
   /// \brief Called on well-formed 'final' clause.
   OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
@@ -7945,7 +7948,7 @@ public:
                                                 SourceLocation StartLoc,
                                                 SourceLocation LParenLoc,
                                                 SourceLocation ArgumentLoc,
-                                                SourceLocation CommaLoc,
+                                                SourceLocation DelimLoc,
                                                 SourceLocation EndLoc);
   /// \brief Called on well-formed 'schedule' clause.
   OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind,

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Sep  3 02:23:48 2015
@@ -602,6 +602,8 @@ public:
 
 void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
   OS << "if(";
+  if (Node->getNameModifier() != OMPD_unknown)
+    OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
   Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
   OS << ")";
 }

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu Sep  3 02:23:48 2015
@@ -288,7 +288,6 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     ConsumeToken();
 
     StmtResult AssociatedStmt;
-    bool CreateDirective = true;
     if (HasAssociatedStatement) {
       // The body is a block scope like in Lambdas and Blocks.
       Sema::CompoundScopeRAII CompoundScope(Actions);
@@ -298,12 +297,10 @@ Parser::ParseOpenMPDeclarativeOrExecutab
       AssociatedStmt = ParseStatement();
       Actions.ActOnFinishOfCompoundStmt();
       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
-      CreateDirective = AssociatedStmt.isUsable();
     }
-    if (CreateDirective)
-      Directive = Actions.ActOnOpenMPExecutableDirective(
-          DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
-          EndLoc);
+    Directive = Actions.ActOnOpenMPExecutableDirective(
+        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
+        EndLoc);
 
     // Exit scope.
     Actions.EndOpenMPDSABlock(Directive.get());
@@ -411,7 +408,6 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   }
 
   switch (CKind) {
-  case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
   case OMPC_safelen:
@@ -420,7 +416,6 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   case OMPC_ordered:
   case OMPC_device:
     // OpenMP [2.5, Restrictions]
-    //  At most one if clause can appear on the directive.
     //  At most one num_threads clause can appear on the directive.
     // OpenMP [2.8.1, simd construct, Restrictions]
     //  Only one safelen  clause can appear on a simd directive.
@@ -432,8 +427,8 @@ OMPClause *Parser::ParseOpenMPClause(Ope
     //  At most one if clause can appear on the directive.
     //  At most one final clause can appear on the directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
-                                               << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause)
+          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
       ErrorFound = true;
     }
 
@@ -450,8 +445,8 @@ OMPClause *Parser::ParseOpenMPClause(Ope
     // OpenMP [2.5, parallel Construct, Restrictions]
     //  At most one proc_bind clause can appear on the directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
-                                               << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause)
+          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
       ErrorFound = true;
     }
 
@@ -461,11 +456,12 @@ OMPClause *Parser::ParseOpenMPClause(Ope
     // OpenMP [2.7.1, Restrictions, p. 3]
     //  Only one schedule clause can appear on a loop directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
-                                               << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause)
+          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
       ErrorFound = true;
     }
 
+  case OMPC_if:
     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
     break;
   case OMPC_nowait:
@@ -481,8 +477,8 @@ OMPClause *Parser::ParseOpenMPClause(Ope
     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
     //  Only one nowait clause can appear on a for directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
-                                               << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause)
+          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
       ErrorFound = true;
     }
 
@@ -515,12 +511,9 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   return ErrorFound ? nullptr : Clause;
 }
 
-/// \brief Parsing of OpenMP clauses with single expressions like 'if',
-/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
-/// 'thread_limit' or 'simdlen'.
-///
-///    if-clause:
-///      'if' '(' expression ')'
+/// \brief Parsing of OpenMP clauses with single expressions like 'final',
+/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 'thread_limit'
+/// or 'simdlen'.
 ///
 ///    final-clause:
 ///      'final' '(' expression ')'
@@ -545,8 +538,10 @@ OMPClause *Parser::ParseOpenMPSingleExpr
                          getOpenMPClauseName(Kind)))
     return nullptr;
 
+  SourceLocation ELoc = Tok.getLocation();
   ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
 
   // Parse ')'.
   T.consumeClose();
@@ -620,9 +615,12 @@ OMPClause *Parser::ParseOpenMPClause(Ope
 ///    schedule-clause:
 ///      'schedule' '(' kind [',' expression ] ')'
 ///
+///    if-clause:
+///      'if' '(' [ directive-name-modifier ':' ] expression ')'
+///
 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = ConsumeToken();
-  SourceLocation CommaLoc;
+  SourceLocation DelimLoc;
   // Parse '('.
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   if (T.expectAndConsume(diag::err_expected_lparen_after,
@@ -630,29 +628,50 @@ OMPClause *Parser::ParseOpenMPSingleExpr
     return nullptr;
 
   ExprResult Val;
-  unsigned Type = getOpenMPSimpleClauseType(
-      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
-  SourceLocation KLoc = Tok.getLocation();
-  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
-      Tok.isNot(tok::annot_pragma_openmp_end))
-    ConsumeAnyToken();
+  unsigned Arg;
+  SourceLocation KLoc;
+  if (Kind == OMPC_schedule) {
+    Arg = getOpenMPSimpleClauseType(
+        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
+    KLoc = Tok.getLocation();
+    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
+        Tok.isNot(tok::annot_pragma_openmp_end))
+      ConsumeAnyToken();
+    if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic ||
+         Arg == OMPC_SCHEDULE_guided) &&
+        Tok.is(tok::comma))
+      DelimLoc = ConsumeAnyToken();
+  } else {
+    assert(Kind == OMPC_if);
+    KLoc = Tok.getLocation();
+    Arg = ParseOpenMPDirectiveKind(*this);
+    if (Arg != OMPD_unknown) {
+      ConsumeToken();
+      if (Tok.is(tok::colon))
+        DelimLoc = ConsumeToken();
+      else
+        Diag(Tok, diag::warn_pragma_expected_colon)
+            << "directive name modifier";
+    }
+  }
 
-  if (Kind == OMPC_schedule &&
-      (Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic ||
-       Type == OMPC_SCHEDULE_guided) &&
-      Tok.is(tok::comma)) {
-    CommaLoc = ConsumeAnyToken();
+  bool NeedAnExpression =
+      (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
+  if (NeedAnExpression) {
+    SourceLocation ELoc = Tok.getLocation();
     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
-    if (Val.isInvalid())
-      return nullptr;
+    Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
   }
 
   // Parse ')'.
   T.consumeClose();
 
+  if (NeedAnExpression && Val.isInvalid())
+    return nullptr;
+
   return Actions.ActOnOpenMPSingleExprWithArgClause(
-      Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc,
+      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
       T.getCloseLocation());
 }
 
@@ -838,9 +857,9 @@ OMPClause *Parser::ParseOpenMPVarListCla
   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
   if (MustHaveTail) {
     ColonLoc = Tok.getLocation();
-    ConsumeToken();
-    ExprResult Tail =
-        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+    SourceLocation ELoc = ConsumeToken();
+    ExprResult Tail = ParseAssignmentExpression();
+    Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
     if (Tail.isUsable())
       TailExpr = Tail.get();
     else

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Sep  3 02:23:48 2015
@@ -1985,6 +1985,82 @@ static bool CheckNestingOfRegions(Sema &
   return false;
 }
 
+static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
+                           ArrayRef<OMPClause *> Clauses,
+                           ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
+  bool ErrorFound = false;
+  unsigned NamedModifiersNumber = 0;
+  SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
+      OMPD_unknown + 1);
+  for (const auto *C : Clauses) {
+    if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
+      // At most one if clause without a directive-name-modifier can appear on
+      // the directive.
+      OpenMPDirectiveKind CurNM = IC->getNameModifier();
+      if (FoundNameModifiers[CurNM]) {
+        S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
+            << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
+            << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
+        ErrorFound = true;
+      } else if (CurNM != OMPD_unknown)
+        ++NamedModifiersNumber;
+      FoundNameModifiers[CurNM] = IC;
+      if (CurNM == OMPD_unknown)
+        continue;
+      // Check if the specified name modifier is allowed for the current
+      // directive.
+      // At most one if clause with the particular directive-name-modifier can
+      // appear on the directive.
+      bool MatchFound = false;
+      for (auto NM : AllowedNameModifiers) {
+        if (CurNM == NM) {
+          MatchFound = true;
+          break;
+        }
+      }
+      if (!MatchFound) {
+        S.Diag(IC->getNameModifierLoc(),
+               diag::err_omp_wrong_if_directive_name_modifier)
+            << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
+        ErrorFound = true;
+      }
+    }
+  }
+  // If any if clause on the directive includes a directive-name-modifier then
+  // all if clauses on the directive must include a directive-name-modifier.
+  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
+    if (NamedModifiersNumber == AllowedNameModifiers.size()) {
+      S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
+             diag::err_omp_no_more_if_clause);
+    } else {
+      std::string Values;
+      std::string Sep(", ");
+      unsigned AllowedCnt = 0;
+      unsigned TotalAllowedNum =
+          AllowedNameModifiers.size() - NamedModifiersNumber;
+      for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
+           ++Cnt) {
+        OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
+        if (!FoundNameModifiers[NM]) {
+          Values += "'";
+          Values += getOpenMPDirectiveName(NM);
+          Values += "'";
+          if (AllowedCnt + 2 == TotalAllowedNum)
+            Values += " or ";
+          else if (AllowedCnt + 1 != TotalAllowedNum)
+            Values += Sep;
+          ++AllowedCnt;
+        }
+      }
+      S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
+             diag::err_omp_unnamed_if_clause)
+          << (TotalAllowedNum > 1) << Values;
+    }
+    ErrorFound = true;
+  }
+  return ErrorFound;
+}
+
 StmtResult Sema::ActOnOpenMPExecutableDirective(
     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
@@ -2021,10 +2097,12 @@ StmtResult Sema::ActOnOpenMPExecutableDi
     }
   }
 
+  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
   switch (Kind) {
   case OMPD_parallel:
     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
                                        EndLoc);
+    AllowedNameModifiers.push_back(OMPD_parallel);
     break;
   case OMPD_simd:
     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
@@ -2064,18 +2142,22 @@ StmtResult Sema::ActOnOpenMPExecutableDi
   case OMPD_parallel_for:
     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
                                           EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_parallel);
     break;
   case OMPD_parallel_for_simd:
     Res = ActOnOpenMPParallelForSimdDirective(
         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_parallel);
     break;
   case OMPD_parallel_sections:
     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
                                                StartLoc, EndLoc);
+    AllowedNameModifiers.push_back(OMPD_parallel);
     break;
   case OMPD_task:
     Res =
         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+    AllowedNameModifiers.push_back(OMPD_task);
     break;
   case OMPD_taskyield:
     assert(ClausesWithImplicit.empty() &&
@@ -2124,6 +2206,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi
   case OMPD_target:
     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
                                      EndLoc);
+    AllowedNameModifiers.push_back(OMPD_target);
     break;
   case OMPD_cancellation_point:
     assert(ClausesWithImplicit.empty() &&
@@ -2142,6 +2225,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi
   case OMPD_target_data:
     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
                                          EndLoc);
+    AllowedNameModifiers.push_back(OMPD_target_data);
     break;
   case OMPD_threadprivate:
     llvm_unreachable("OpenMP Directive is not allowed");
@@ -2153,8 +2237,11 @@ StmtResult Sema::ActOnOpenMPExecutableDi
     Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
         << P.first << P.second->getSourceRange();
   }
-  if (!VarsWithInheritedDSA.empty())
-    return StmtError();
+  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
+
+  if (!AllowedNameModifiers.empty())
+    ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
+                 ErrorFound;
 
   if (ErrorFound)
     return StmtError();
@@ -2165,7 +2252,9 @@ StmtResult Sema::ActOnOpenMPParallelDire
                                               Stmt *AStmt,
                                               SourceLocation StartLoc,
                                               SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   CapturedStmt *CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -3557,6 +3646,10 @@ StmtResult Sema::ActOnOpenMPSimdDirectiv
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
     llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
   OMPLoopDirective::HelperExprs B;
   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
   // define the nested loops number.
@@ -3606,6 +3699,10 @@ StmtResult Sema::ActOnOpenMPForDirective
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
     llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
   OMPLoopDirective::HelperExprs B;
   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
   // define the nested loops number.
@@ -3637,6 +3734,10 @@ StmtResult Sema::ActOnOpenMPForSimdDirec
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
     llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
   OMPLoopDirective::HelperExprs B;
   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
   // define the nested loops number.
@@ -3687,7 +3788,10 @@ StmtResult Sema::ActOnOpenMPSectionsDire
                                               Stmt *AStmt,
                                               SourceLocation StartLoc,
                                               SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
   auto BaseStmt = AStmt;
   while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
     BaseStmt = CS->getCapturedStmt();
@@ -3719,7 +3823,10 @@ StmtResult Sema::ActOnOpenMPSectionsDire
 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
                                              SourceLocation StartLoc,
                                              SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -3730,7 +3837,10 @@ StmtResult Sema::ActOnOpenMPSingleDirect
                                             Stmt *AStmt,
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -3757,7 +3867,10 @@ StmtResult Sema::ActOnOpenMPSingleDirect
 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -3768,7 +3881,10 @@ StmtResult
 Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
                                    Stmt *AStmt, SourceLocation StartLoc,
                                    SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -3780,7 +3896,9 @@ StmtResult Sema::ActOnOpenMPParallelForD
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
     llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   CapturedStmt *CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -3821,7 +3939,9 @@ StmtResult Sema::ActOnOpenMPParallelForS
     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
     SourceLocation EndLoc,
     llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   CapturedStmt *CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -3877,7 +3997,10 @@ StmtResult
 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
                                            Stmt *AStmt, SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
   auto BaseStmt = AStmt;
   while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
     BaseStmt = CS->getCapturedStmt();
@@ -3910,7 +4033,9 @@ Sema::ActOnOpenMPParallelSectionsDirecti
 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
                                           Stmt *AStmt, SourceLocation StartLoc,
                                           SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   CapturedStmt *CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -3942,7 +4067,10 @@ StmtResult Sema::ActOnOpenMPTaskwaitDire
 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
                                                SourceLocation StartLoc,
                                                SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -3959,7 +4087,10 @@ StmtResult Sema::ActOnOpenMPFlushDirecti
 StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt,
                                              SourceLocation StartLoc,
                                              SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
 
@@ -4210,7 +4341,9 @@ StmtResult Sema::ActOnOpenMPAtomicDirect
                                             Stmt *AStmt,
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   auto CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -4631,7 +4764,10 @@ StmtResult Sema::ActOnOpenMPTargetDirect
                                             Stmt *AStmt,
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   // OpenMP [2.16, Nesting of Regions]
   // If specified, a teams construct must be contained within a target
@@ -4672,6 +4808,11 @@ StmtResult Sema::ActOnOpenMPTargetDataDi
                                                 Stmt *AStmt,
                                                 SourceLocation StartLoc,
                                                 SourceLocation EndLoc) {
+  if (!AStmt)
+    return StmtError();
+
+  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
   getCurFunction()->setHasBranchProtectedScope();
 
   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
@@ -4681,7 +4822,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDi
 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
                                            Stmt *AStmt, SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  if (!AStmt)
+    return StmtError();
+
   CapturedStmt *CS = cast<CapturedStmt>(AStmt);
   // 1.2.2 OpenMP Language Terminology
   // Structured block - An executable statement with a single entry at the
@@ -4743,9 +4886,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
                                              SourceLocation EndLoc) {
   OMPClause *Res = nullptr;
   switch (Kind) {
-  case OMPC_if:
-    Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc);
-    break;
   case OMPC_final:
     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
@@ -4767,6 +4907,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
   case OMPC_device:
     Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_if:
   case OMPC_default:
   case OMPC_proc_bind:
   case OMPC_schedule:
@@ -4796,8 +4937,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
   return Res;
 }
 
-OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
+                                     Expr *Condition, SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
+                                     SourceLocation NameModifierLoc,
+                                     SourceLocation ColonLoc,
                                      SourceLocation EndLoc) {
   Expr *ValExpr = Condition;
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
@@ -4811,7 +4955,8 @@ OMPClause *Sema::ActOnOpenMPIfClause(Exp
     ValExpr = Val.get();
   }
 
-  return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
+                                   NameModifierLoc, ColonLoc, EndLoc);
 }
 
 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
@@ -5129,16 +5274,20 @@ OMPClause *Sema::ActOnOpenMPProcBindClau
 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
     OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
     SourceLocation StartLoc, SourceLocation LParenLoc,
-    SourceLocation ArgumentLoc, SourceLocation CommaLoc,
+    SourceLocation ArgumentLoc, SourceLocation DelimLoc,
     SourceLocation EndLoc) {
   OMPClause *Res = nullptr;
   switch (Kind) {
   case OMPC_schedule:
     Res = ActOnOpenMPScheduleClause(
         static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
-        LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
+        LParenLoc, ArgumentLoc, DelimLoc, EndLoc);
     break;
   case OMPC_if:
+    Res =
+        ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument), Expr,
+                            StartLoc, LParenLoc, ArgumentLoc, DelimLoc, EndLoc);
+    break;
   case OMPC_final:
   case OMPC_num_threads:
   case OMPC_safelen:
@@ -6382,9 +6531,7 @@ OMPClause *Sema::ActOnOpenMPReductionCla
             BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
                        BO_Assign, LHSDRE, ConditionalOp);
       }
-      if (ReductionOp.isUsable()) {
-        ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
-      }
+      ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
     }
     if (ReductionOp.isInvalid())
       continue;
@@ -6551,6 +6698,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause
         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
     ExprResult CalcStep =
         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
+    CalcStep = ActOnFinishFullExpr(CalcStep.get());
 
     // Warn about zero linear step (it would be probably better specified as
     // making corresponding variables 'const').
@@ -6607,13 +6755,15 @@ static bool FinishOpenMPLinearClause(OMP
     ExprResult Update =
         BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
                            InitExpr, IV, Step, /* Subtract */ false);
-    Update = SemaRef.ActOnFinishFullExpr(Update.get());
+    Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
+                                         /*DiscardedValue=*/true);
 
     // Build final: Var = InitExpr + NumIterations * Step
     ExprResult Final =
         BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
                            InitExpr, NumIterations, Step, /* Subtract */ false);
-    Final = SemaRef.ActOnFinishFullExpr(Final.get());
+    Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
+                                        /*DiscardedValue=*/true);
     if (!Update.isUsable() || !Final.isUsable()) {
       Updates.push_back(nullptr);
       Finals.push_back(nullptr);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Sep  3 02:23:48 2015
@@ -1355,12 +1355,15 @@ public:
   ///
   /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
-  OMPClause *RebuildOMPIfClause(Expr *Condition,
-                                SourceLocation StartLoc,
+  OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
+                                Expr *Condition, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
+                                SourceLocation NameModifierLoc,
+                                SourceLocation ColonLoc,
                                 SourceLocation EndLoc) {
-    return getSema().ActOnOpenMPIfClause(Condition, StartLoc,
-                                         LParenLoc, EndLoc);
+    return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
+                                         LParenLoc, NameModifierLoc, ColonLoc,
+                                         EndLoc);
   }
 
   /// \brief Build a new OpenMP 'final' clause.
@@ -7214,8 +7217,9 @@ OMPClause *TreeTransform<Derived>::Trans
   ExprResult Cond = getDerived().TransformExpr(C->getCondition());
   if (Cond.isInvalid())
     return nullptr;
-  return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(),
-                                         C->getLParenLoc(), C->getLocEnd());
+  return getDerived().RebuildOMPIfClause(
+      C->getNameModifier(), Cond.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getNameModifierLoc(), C->getColonLoc(), C->getLocEnd());
 }
 
 template <typename Derived>

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Sep  3 02:23:48 2015
@@ -1812,6 +1812,9 @@ OMPClause *OMPClauseReader::readClause()
 }
 
 void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) {
+  C->setNameModifier(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
+  C->setNameModifierLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
   C->setCondition(Reader->Reader.ReadSubExpr());
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
 }

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Sep  3 02:23:48 2015
@@ -1728,6 +1728,9 @@ void OMPClauseWriter::writeClause(OMPCla
 }
 
 void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
+  Record.push_back(C->getNameModifier());
+  Writer->Writer.AddSourceLocation(C->getNameModifierLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
   Writer->Writer.AddStmt(C->getCondition());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
 }

Modified: cfe/trunk/test/OpenMP/for_schedule_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_schedule_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_schedule_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_schedule_messages.cpp Thu Sep  3 02:23:48 2015
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
-  #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   // expected-error at +1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -76,14 +76,14 @@ int main(int argc, char **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +3 {{statement after '#pragma omp for' must be a for loop}}
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
-  #pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   foo();
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
   return tmain<int, char, 1, 0>(argc, argv);

Modified: cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp Thu Sep  3 02:23:48 2015
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
-  #pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
+  #pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   // expected-error at +1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -76,14 +76,14 @@ int main(int argc, char **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
+  #pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +3 {{statement after '#pragma omp for simd' must be a for loop}}
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
-  #pragma omp for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   foo();
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
   return tmain<int, char, 1, 0>(argc, argv);

Modified: cfe/trunk/test/OpenMP/parallel_for_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -34,6 +34,20 @@ int tmain(T argc, S **argv) {
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for if(argc)
   for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
 
   return 0;
 }
@@ -64,6 +78,20 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
 
   return tmain(argc, argv);
 }

Modified: cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp Thu Sep  3 02:23:48 2015
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
-  #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   // expected-error at +1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -76,14 +76,14 @@ int main(int argc, char **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +3 {{statement after '#pragma omp parallel for' must be a for loop}}
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
-  #pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   foo();
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
   return tmain<int, char, 1, 0>(argc, argv);

Modified: cfe/trunk/test/OpenMP/parallel_for_simd_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_simd_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_simd_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -34,6 +34,20 @@ int tmain(T argc, S **argv) {
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(argc)
   for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
 
   return 0;
 }
@@ -64,6 +78,20 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
 
   return tmain(argc, argv);
 }

Modified: cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp Thu Sep  3 02:23:48 2015
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
-  #pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
+  #pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   // expected-error at +1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -76,14 +76,14 @@ int main(int argc, char **argv) {
   // expected-error at +1 {{argument to 'schedule' clause must be a positive integer value}}
   #pragma omp parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
+  #pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   #pragma omp parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error at +3 {{statement after '#pragma omp parallel for simd' must be a for loop}}
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
-  #pragma omp parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   foo();
   // expected-note at +1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
   return tmain<int, char, 1, 0>(argc, argv);

Modified: cfe/trunk/test/OpenMP/parallel_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -22,6 +22,13 @@ int tmain(T argc, S **argv) {
   #pragma omp parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(argc)
+  #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : argc)
+  #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}}
+  #pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return 0;
@@ -40,6 +47,13 @@ int main(int argc, char **argv) {
   #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel : argc)
+  #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}}
+  #pragma omp parallel if(parallel : argc) if (parallel:argc)  // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return tmain(argc, argv);

Modified: cfe/trunk/test/OpenMP/parallel_sections_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_sections_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_sections_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_sections_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -55,6 +55,30 @@ int tmain(T argc, S **argv) {
   {
     foo();
   }
+  #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc)
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  {
+    foo();
+  }
 
   return 0;
 }
@@ -108,6 +132,30 @@ int main(int argc, char **argv) {
   {
     foo();
   }
+  #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc)
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
+  {
+    foo();
+  }
 
   return tmain(argc, argv);
 }

Modified: cfe/trunk/test/OpenMP/target_data_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_data_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_data_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_data_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -20,6 +20,12 @@ int main(int argc, char **argv) {
   #pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}}
   #pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}}
   #pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target data if(target data : argc)
+  #pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}}
+  #pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}}
+  #pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return 0;

Modified: cfe/trunk/test/OpenMP/target_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -22,6 +22,12 @@ int tmain(T argc, S **argv) {
   #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp target if(argc)
+  #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target if(target : argc)
+  #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
+  #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
+  #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return 0;
@@ -40,6 +46,12 @@ int main(int argc, char **argv) {
   #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp target if(target : argc)
+  #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
+  #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
+  #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return tmain(argc, argv);

Modified: cfe/trunk/test/OpenMP/task_if_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_if_messages.cpp?rev=246747&r1=246746&r2=246747&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/task_if_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/task_if_messages.cpp Thu Sep  3 02:23:48 2015
@@ -22,6 +22,12 @@ int tmain(T argc, S **argv) {
   #pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp task if(argc)
+  #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(task : argc)
+  #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}}
+  #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}}
+  #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return 0;
@@ -40,6 +46,12 @@ int main(int argc, char **argv) {
   #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp task if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp task if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(task : argc)
+  #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}}
+  #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}}
+  #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
   foo();
 
   return tmain(argc, argv);




More information about the cfe-commits mailing list