[flang] [llvm] [flang][Parser][OpenMP] Fix unparser for cancellation_construct_type (PR #136001)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 16 11:28:37 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-parser

Author: Tom Eccles (tblah)

<details>
<summary>Changes</summary>

Previously the unparser would print like
```
!$OMP CANCEL CANCELLATION_CONSTRUCT_TYPE(SECTIONS)
```

This is not valid Fortran. I have fixed it to print without the clause name.

---
Full diff: https://github.com/llvm/llvm-project/pull/136001.diff


6 Files Affected:

- (modified) flang/lib/Parser/unparse.cpp (+4) 
- (added) flang/test/Parser/OpenMP/cancel.f90 (+53) 
- (modified) llvm/include/llvm/Frontend/Directive/DirectiveBase.td (+3) 
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+1) 
- (modified) llvm/include/llvm/TableGen/DirectiveEmitter.h (+4) 
- (modified) llvm/utils/TableGen/Basic/DirectiveEmitter.cpp (+2) 


``````````diff
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 47dae0ae753d2..35fb0790b633d 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2871,6 +2871,10 @@ class UnparseVisitor {
     Put("\n");
     EndOpenMP();
   }
+  // Clause unparsers are usually generated by tablegen in the form
+  // CLAUSE(VALUE). Here we only want to print VALUE so a custom unparser is
+  // needed.
+  void Unparse(const OmpClause::CancellationConstructType &x) { Walk(x.v); }
   void Unparse(const OpenMPCancellationPointConstruct &x) {
     BeginOpenMP();
     Word("!$OMP ");
diff --git a/flang/test/Parser/OpenMP/cancel.f90 b/flang/test/Parser/OpenMP/cancel.f90
new file mode 100644
index 0000000000000..f5c1309e0d8c1
--- /dev/null
+++ b/flang/test/Parser/OpenMP/cancel.f90
@@ -0,0 +1,53 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck %s
+
+! CHECK: SUBROUTINE parallel
+subroutine parallel
+! CHECK: !$OMP PARALLEL
+  !$omp parallel
+! CHECK: !$OMP CANCEL PARALLEL
+    !$omp cancel parallel
+! CHECK: !$OMP END PARALLEL
+  !$omp end parallel
+! CHECK: END SUBROUTINE
+end subroutine
+
+! CHECK: SUBROUTINE sections
+subroutine sections
+! CHECK: !$OMP PARALLEL SECTIONS
+  !$omp parallel sections
+! CHECK: !$OMP CANCEL SECTIONS
+    !$omp cancel sections
+! CHECK: !$OMP END PARALLEL SECTIONS
+  !$omp end parallel sections
+! CHECK: END SUBROUTINE
+end subroutine
+
+! CHECK: SUBROUTINE loop
+subroutine loop
+! CHECK: !$OMP PARALLEL DO
+  !$omp parallel do
+! CHECK: DO i=1_4,10_4
+    do i=1,10
+! CHECK: !$OMP CANCEL DO
+      !$omp cancel do
+! CHECK: END DO
+    enddo
+! CHECK: !$OMP END PARALLEL DO
+  !$omp end parallel do
+! CHECK: END SUBROUTINE
+end subroutine
+
+! CHECK: SUBROUTINE taskgroup
+subroutine taskgroup
+! CHECK: !$OMP TASKGROUP
+  !$omp taskgroup
+! CHECK: !$OMP TASK
+    !$omp task
+! CHECK: !$OMP CANCEL TASKGROUP
+      !$omp cancel taskgroup
+! CHECK: !$OMP END TASK
+    !$omp end task
+! CHECK: !$OMP END TASKGROUP
+  !$omp end taskgroup
+! CHECK: END SUBROUTINE
+end subroutine
diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
index 707239c7ba364..745eccc9b147f 100644
--- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -83,6 +83,9 @@ class Clause<string c> {
   // Optional class holding value of the clause in flang AST.
   string flangClass = "";
 
+  // If set to true, don't emit flang Unparser.
+  bit skipFlangUnparser = false;
+
   // If set to true, value is optional. Not optional by default.
   bit isValueOptional = false;
 
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index e2a1449d8cc76..1f286abaa9679 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -106,6 +106,7 @@ def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
     OMP_CANCELLATION_CONSTRUCT_None
   ];
   let flangClass = "OmpCancellationConstructTypeClause";
+  let skipFlangUnparser = true;
 }
 def OMPC_Contains : Clause<"contains"> {
   let clangClass = "OMPContainsClause";
diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h b/llvm/include/llvm/TableGen/DirectiveEmitter.h
index a2c9b2d427cce..78b0b24d4d4c0 100644
--- a/llvm/include/llvm/TableGen/DirectiveEmitter.h
+++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h
@@ -209,6 +209,10 @@ class Clause : public BaseRecord {
     return Def->getValueAsListOfDefs("allowedClauseValues");
   }
 
+  bool skipFlangUnparser() const {
+    return Def->getValueAsBit("skipFlangUnparser");
+  }
+
   bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
 
   bool isValueList() const { return Def->getValueAsBit("isValueList"); }
diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
index ab68e028f1e96..9f8404b02a141 100644
--- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
@@ -912,6 +912,8 @@ static void generateFlangClauseUnparse(const DirectiveLanguage &DirLang,
   OS << "\n";
 
   for (const Clause Clause : DirLang.getClauses()) {
+    if (Clause.skipFlangUnparser())
+      continue;
     if (!Clause.getFlangClass().empty()) {
       if (Clause.isValueOptional() && Clause.getDefaultValue().empty()) {
         OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()

``````````

</details>


https://github.com/llvm/llvm-project/pull/136001


More information about the llvm-commits mailing list