[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.

llvm-svn: 246747
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ea31260..b4a6768 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1985,6 +1985,82 @@
   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 @@
     }
   }
 
+  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 @@
   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 @@
   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 @@
   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 @@
     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 @@
                                               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 @@
     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 @@
     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 @@
     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 @@
                                               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::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 @@
                                             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::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 @@
 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 @@
     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 @@
     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 @@
 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 @@
 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::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::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 @@
                                             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 @@
                                             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 @@
                                                 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::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 @@
                                              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 @@
   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 @@
   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 @@
     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::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 @@
             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 @@
         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 @@
     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);