[OPENMP50]Basic parsing/sema analysis for order(concurrent) clause.
Added parsing/sema/serialization support for order(concurrent) clause in
loop|simd-based directives.
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index cb08079..df76b42 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Sema/Initialization.h"
@@ -3871,6 +3872,36 @@
}
}
+static bool checkOrderedOrderSpecified(Sema &S,
+ const ArrayRef<OMPClause *> Clauses) {
+ const OMPOrderedClause *Ordered = nullptr;
+ const OMPOrderClause *Order = nullptr;
+
+ for (const OMPClause *Clause : Clauses) {
+ if (Clause->getClauseKind() == OMPC_ordered)
+ Ordered = cast<OMPOrderedClause>(Clause);
+ else if (Clause->getClauseKind() == OMPC_order) {
+ Order = cast<OMPOrderClause>(Clause);
+ if (Order->getKind() != OMPC_ORDER_concurrent)
+ Order = nullptr;
+ }
+ if (Ordered && Order)
+ break;
+ }
+
+ if (Ordered && Order) {
+ S.Diag(Order->getKindKwLoc(),
+ diag::err_omp_simple_clause_incompatible_with_ordered)
+ << getOpenMPClauseName(OMPC_order)
+ << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
+ << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
+ S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
+ << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
+ return true;
+ }
+ return false;
+}
+
StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
ArrayRef<OMPClause *> Clauses) {
bool ErrorFound = false;
@@ -3941,10 +3972,18 @@
Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
? SC->getFirstScheduleModifierLoc()
: SC->getSecondScheduleModifierLoc(),
- diag::err_omp_schedule_nonmonotonic_ordered)
+ diag::err_omp_simple_clause_incompatible_with_ordered)
+ << getOpenMPClauseName(OMPC_schedule)
+ << getOpenMPSimpleClauseTypeName(OMPC_schedule,
+ OMPC_SCHEDULE_MODIFIER_nonmonotonic)
<< SourceRange(OC->getBeginLoc(), OC->getEndLoc());
ErrorFound = true;
}
+ // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
+ // If an order(concurrent) clause is present, an ordered clause may not appear
+ // on the same directive.
+ if (checkOrderedOrderSpecified(*this, Clauses))
+ ErrorFound = true;
if (!LCs.empty() && OC && OC->getNumForLoops()) {
for (const OMPLinearClause *C : LCs) {
Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
@@ -4959,6 +4998,7 @@
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
case OMPC_nontemporal:
+ case OMPC_order:
continue;
case OMPC_allocator:
case OMPC_flush:
@@ -4979,7 +5019,7 @@
DSAChecker.Visit(CC);
}
}
- for (auto &P : DSAChecker.getVarsWithInheritedDSA())
+ for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
}
for (const auto &P : VarsWithInheritedDSA) {
@@ -8588,7 +8628,7 @@
SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
<< (TC != nullptr);
- Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
+ Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
ErrorFound = true;
}
}
@@ -10822,6 +10862,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -11533,6 +11574,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Unexpected OpenMP clause.");
}
return CaptureRegion;
@@ -11898,6 +11940,10 @@
static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_order:
+ Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -12043,6 +12089,24 @@
LParenLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_ORDER_unknown) {
+ static_assert(OMPC_ORDER_unknown > 0,
+ "OMPC_ORDER_unknown not greater than 0");
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_order, /*First=*/0,
+ /*Last=*/OMPC_ORDER_unknown)
+ << getOpenMPClauseName(OMPC_order);
+ return nullptr;
+ }
+ return new (Context)
+ OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -12137,6 +12201,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12349,6 +12414,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12572,6 +12638,7 @@
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;