[flang-commits] [flang] [llvm] [flang][OpenMP] Move clause validity checks into OpenMP-specific code (PR #205607)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Thu Jun 25 10:51:24 PDT 2026
================
@@ -878,6 +886,150 @@ void OmpStructureChecker::CheckDirectiveDeprecation(
// one another, but only the top-level directive should cause a warning.
}
+std::pair<const parser::OmpClause *, const parser::OmpClause *>
+OmpStructureChecker::FindMutuallyExclusiveClauses(
+ OmpClauseSet exclusive, const parser::OmpClauseList &clauses) {
+ const parser::OmpClause *first{nullptr};
+ for (const parser::OmpClause &clause : clauses.v) {
+ llvm::omp::Clause clauseId{clause.Id()};
+ if (!exclusive.test(clauseId)) {
+ continue;
+ }
+ if (first) {
+ llvm::omp::Clause firstId{first->Id()};
+ if (clauseId < firstId) {
+ return std::make_pair(&clause, first);
+ } else if (clauseId > firstId) {
+ return std::make_pair(first, &clause);
+ }
+ } else {
+ first = &clause;
+ }
+ }
+ return std::make_pair(nullptr, nullptr);
+}
+
+void OmpStructureChecker::CheckExclusiveClauses(
+ OmpClauseSet exclusive, const parser::OmpDirectiveSpecification &spec) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ auto pair{FindMutuallyExclusiveClauses(exclusive, spec.Clauses())};
+
+ if (pair.first && pair.second) {
+ std::string firstName{GetUpperName(pair.first->Id(), version)};
+ std::string secondName{GetUpperName(pair.second->Id(), version)};
+ context_
+ .Say(pair.second->source,
+ "%s and %s clauses are mutually exclusive and may not appear on the same %s directive"_err_en_US,
+ firstName, secondName, GetUpperName(spec.DirId(), version))
+ .Attach(pair.first->source, "%s clause was specified here"_en_US,
+ firstName);
+ }
+}
+
+void OmpStructureChecker::CheckClauses(parser::OmpDirectiveName dirName,
+ llvm::iterator_range<ClauseIterator> beginClauses,
+ llvm::iterator_range<ClauseIterator> endClauses) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ llvm::omp::Directive dirId{dirName.v};
+ std::vector<const parser::OmpClause *> allClauses;
+
+ auto addClause{[&](const parser::OmpClause &clause) {
+ llvm::omp::Clause clauseId{clause.Id()};
+ AddClauseToCrtContext(clauseId);
+ SetContextClause(clause);
+ SetContextClauseInfo(clauseId);
+ allClauses.push_back(&clause);
+ }};
+
+ for (const parser::OmpClause &clause : beginClauses) {
+ addClause(clause);
+ }
+ for (const parser::OmpClause &clause : endClauses) {
+ llvm::omp::Clause clauseId{clause.Id()};
+ if (llvm::omp::isEndClause(clauseId)) {
+ addClause(clause);
+ } else {
+ context_.Say(clause.source,
+ "%s clause is not allowed on an end-directive"_err_en_US,
----------------
abidh wrote:
Ultra nit: could we use the directive name with end instead of generic end-directive.
https://github.com/llvm/llvm-project/pull/205607
More information about the flang-commits
mailing list