[flang-commits] [flang] [Flang][Parser] Refactor parse tree enumerations into common header (PR #65339)

Sergio Afonso via flang-commits flang-commits at lists.llvm.org
Tue Sep 5 08:38:46 PDT 2023


https://github.com/skatrak created https://github.com/llvm/llvm-project/pull/65339:

This patch moves all `ENUM_CLASS` definitions from `flang/Parser/parse-tree.h` to `flang/Common/Fortran.h` so they can be used without including the much larger header defining all parse tree nodes. This is to address a suggestion to patch [D157983](https://reviews.llvm.org/D157983).

These enumerations have been renamed, since they are now placed in a more top-level namespace rather than inside of parse tree node classes, so I would be looking for reviewers to also make sure that these names make sense and to propose any changes to improve them.

>From 6cfaffa62675526083a9077b05140ba1c48f507a Mon Sep 17 00:00:00 2001
From: Sergio Afonso <safonsof at amd.com>
Date: Tue, 5 Sep 2023 16:28:09 +0100
Subject: [PATCH] [Flang][Parser] Refactor parse tree enumerations into common
 header

This patch moves all `ENUM_CLASS` definitions from `flang/Parser/parse-tree.h`
to `flang/Common/Fortran.h` so they can be used without including the much
larger header defining all parse tree nodes.
---
 flang/include/flang/Common/Fortran.h          |  77 ++++++++
 flang/include/flang/Parser/dump-parse-tree.h  |  64 +++----
 flang/include/flang/Parser/parse-tree.h       | 118 +++++-------
 flang/lib/Lower/IO.cpp                        |  83 ++++----
 flang/lib/Lower/OpenACC.cpp                   |  54 +++---
 flang/lib/Lower/OpenMP.cpp                    | 179 +++++++++---------
 flang/lib/Lower/Runtime.cpp                   |   4 +-
 flang/lib/Parser/Fortran-parsers.cpp          |  86 +++++----
 flang/lib/Parser/executable-parsers.cpp       |   4 +-
 flang/lib/Parser/io-parsers.cpp               | 116 ++++++------
 flang/lib/Parser/openacc-parsers.cpp          |  26 +--
 flang/lib/Parser/openmp-parsers.cpp           | 147 +++++++-------
 flang/lib/Parser/program-parsers.cpp          |   8 +-
 flang/lib/Parser/unparse.cpp                  | 139 +++++++-------
 flang/lib/Semantics/check-acc-structure.cpp   |  44 ++---
 flang/lib/Semantics/check-do-forall.cpp       |   4 +-
 flang/lib/Semantics/check-io.cpp              |  14 +-
 flang/lib/Semantics/check-omp-structure.cpp   | 100 +++++-----
 flang/lib/Semantics/check-omp-structure.h     |  11 +-
 flang/lib/Semantics/resolve-directives.cpp    |  11 +-
 flang/lib/Semantics/resolve-labels.cpp        |   7 +-
 flang/lib/Semantics/resolve-names-utils.cpp   |   2 +-
 flang/lib/Semantics/resolve-names.cpp         |  28 +--
 flang/lib/Semantics/tools.cpp                 |   3 +-
 .../OpenMP/declare_target-device_type.f90     |   6 +-
 flang/test/Parser/OpenMP/order-clause01.f90   |  50 ++---
 26 files changed, 712 insertions(+), 673 deletions(-)

diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h
index 59d82744fea7111..a5eb1924ebe8d45 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -75,6 +75,83 @@ enum class RoundingMode : std::uint8_t {
   TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
 };
 
+ENUM_CLASS(IntrinsicOperator, Power, Multiply, Divide, Add, Subtract, Concat,
+    LT, LE, EQ, NE, GE, GT, NOT, AND, OR, EQV, NEQV)
+
+ENUM_CLASS(AccessSpecKind, Public, Private)
+
+ENUM_CLASS(IntentSpecKind, In, Out, InOut)
+
+ENUM_CLASS(BindEntityKind, Object, Common)
+
+ENUM_CLASS(SavedEntityKind, Entity, Common)
+
+ENUM_CLASS(ImplicitNoneNameSpec, External, Type) // R866
+
+ENUM_CLASS(StopKind, Stop, ErrorStop)
+
+ENUM_CLASS(ConnectCharExprKind, Access, Action, Asynchronous, Blank, Decimal,
+    Delim, Encoding, Form, Pad, Position, Round, Sign,
+    /* extensions: */ Carriagecontrol, Convert, Dispose)
+
+ENUM_CLASS(
+    IoControlCharExprKind, Advance, Blank, Decimal, Delim, Pad, Round, Sign)
+
+ENUM_CLASS(InquireCharVarKind, Access, Action, Asynchronous, Blank, Decimal,
+    Delim, Direct, Encoding, Form, Formatted, Iomsg, Name, Pad, Position, Read,
+    Readwrite, Round, Sequential, Sign, Stream, Status, Unformatted, Write,
+    /* extensions: */ Carriagecontrol, Convert, Dispose)
+
+ENUM_CLASS(InquireIntVarKind, Iostat, Nextrec, Number, Pos, Recl, Size)
+
+ENUM_CLASS(InquireLogVarKind, Exist, Named, Opened, Pending)
+
+ENUM_CLASS(ModuleNature, Intrinsic, Non_Intrinsic) // R1410
+
+ENUM_CLASS(ProcedureKind, ModuleProcedure, Procedure)
+
+// OpenMP kinds
+ENUM_CLASS(OmpProcBindClauseKind, Close, Master, Spread, Primary)
+
+ENUM_CLASS(OmpDefaultClauseKind, Private, Firstprivate, Shared, None)
+
+ENUM_CLASS(OmpMapKind, To, From, Tofrom, Alloc, Release, Delete)
+
+ENUM_CLASS(OmpDefaultmapClauseImplicitBehavior, Alloc, To, From, Tofrom,
+    Firstprivate, None, Default)
+
+ENUM_CLASS(OmpDefaultmapClauseVariableCategory, Scalar, Aggregate, Allocatable,
+    Pointer)
+
+ENUM_CLASS(OmpScheduleModifierKind, Monotonic, Nonmonotonic, Simd)
+
+ENUM_CLASS(OmpScheduleClauseKind, Static, Dynamic, Guided, Auto, Runtime)
+
+ENUM_CLASS(OmpDeviceClauseDeviceModifier, Ancestor, Device_Num)
+
+ENUM_CLASS(OmpDeviceTypeClauseKind, Any, Host, Nohost)
+
+ENUM_CLASS(OmpIfClauseDirectiveNameModifier, Parallel, Simd, Target, TargetData,
+    TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams)
+
+ENUM_CLASS(OmpOrderModifierKind, Reproducible, Unconstrained)
+
+ENUM_CLASS(OmpOrderClauseKind, Concurrent)
+
+ENUM_CLASS(OmpLinearModifierKind, Ref, Val, Uval)
+
+ENUM_CLASS(OmpDependenceKind, In, Out, Inout, Source, Sink)
+
+ENUM_CLASS(OmpAtomicDefaultMemOrderClauseKind, SeqCst, AcqRel, Relaxed)
+
+ENUM_CLASS(OmpCancelKind, Parallel, Sections, Do, Taskgroup)
+
+// OpenACC kinds
+ENUM_CLASS(AccDataModifierKind, ReadOnly, Zero)
+
+ENUM_CLASS(AccReductionOperatorKind, Plus, Multiply, Max, Min, Iand, Ior, Ieor,
+    And, Or, Eqv, Neqv)
+
 // Fortran label. Must be in [1..99999].
 using Label = std::uint64_t;
 
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 7a009e8cc708284..10659173fea4cea 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -79,7 +79,7 @@ class ParseTreeDumper {
   NODE(parser, AccClauseList)
   NODE(parser, AccCombinedDirective)
   NODE(parser, AccDataModifier)
-  NODE_ENUM(parser::AccDataModifier, Modifier)
+  NODE_ENUM(common, AccDataModifierKind)
   NODE(parser, AccDeclarativeDirective)
   NODE(parser, AccEndAtomic)
   NODE(parser, AccEndBlockDirective)
@@ -95,7 +95,7 @@ class ParseTreeDumper {
   NODE(parser, AccObjectListWithModifier)
   NODE(parser, AccObjectListWithReduction)
   NODE(parser, AccReductionOperator)
-  NODE_ENUM(parser::AccReductionOperator, Operator)
+  NODE_ENUM(common, AccReductionOperatorKind)
   NODE(parser, AccSizeExpr)
   NODE(parser, AccSizeExprList)
   NODE(parser, AccSelfClause)
@@ -118,7 +118,7 @@ class ParseTreeDumper {
   NODE(parser, AccessStmt)
   NODE(parser, AccessId)
   NODE(parser, AccessSpec)
-  NODE_ENUM(AccessSpec, Kind)
+  NODE_ENUM(common, AccessSpecKind)
   NODE(parser, AcSpec)
   NODE(parser, ActionStmt)
   NODE(parser, ActualArg)
@@ -164,7 +164,7 @@ class ParseTreeDumper {
   NODE(BindAttr, Deferred)
   NODE(BindAttr, Non_Overridable)
   NODE(parser, BindEntity)
-  NODE_ENUM(BindEntity, Kind)
+  NODE_ENUM(common, BindEntityKind)
   NODE(parser, BindStmt)
   NODE(parser, Block)
   NODE(parser, BlockConstruct)
@@ -219,7 +219,7 @@ class ParseTreeDumper {
   NODE(parser, ConcurrentHeader)
   NODE(parser, ConnectSpec)
   NODE(ConnectSpec, CharExpr)
-  NODE_ENUM(ConnectSpec::CharExpr, Kind)
+  NODE_ENUM(common, ConnectCharExprKind)
   NODE(ConnectSpec, Newunit)
   NODE(ConnectSpec, Recl)
   NODE(parser, ContainsStmt)
@@ -255,7 +255,7 @@ class ParseTreeDumper {
   NODE(parser, DeferredShapeSpecList)
   NODE(parser, DefinedOpName)
   NODE(parser, DefinedOperator)
-  NODE_ENUM(DefinedOperator, IntrinsicOperator)
+  NODE_ENUM(common, IntrinsicOperator)
   NODE(parser, DerivedTypeDef)
   NODE(parser, DerivedTypeSpec)
   NODE(parser, DerivedTypeStmt)
@@ -376,7 +376,7 @@ class ParseTreeDumper {
   NODE(parser, ImplicitPartStmt)
   NODE(parser, ImplicitSpec)
   NODE(parser, ImplicitStmt)
-  NODE_ENUM(ImplicitStmt, ImplicitNoneNameSpec)
+  NODE_ENUM(common, ImplicitNoneNameSpec)
   NODE(parser, ImpliedShapeSpec)
   NODE(parser, ImportStmt)
   NODE(parser, Initialization)
@@ -384,16 +384,16 @@ class ParseTreeDumper {
   NODE(parser, InputItem)
   NODE(parser, InquireSpec)
   NODE(InquireSpec, CharVar)
-  NODE_ENUM(InquireSpec::CharVar, Kind)
+  NODE_ENUM(common, InquireCharVarKind)
   NODE(InquireSpec, IntVar)
-  NODE_ENUM(InquireSpec::IntVar, Kind)
+  NODE_ENUM(common, InquireIntVarKind)
   NODE(InquireSpec, LogVar)
-  NODE_ENUM(InquireSpec::LogVar, Kind)
+  NODE_ENUM(common, InquireLogVarKind)
   NODE(parser, InquireStmt)
   NODE(InquireStmt, Iolength)
   NODE(parser, IntegerTypeSpec)
   NODE(parser, IntentSpec)
-  NODE_ENUM(IntentSpec, Intent)
+  NODE_ENUM(common, IntentSpecKind)
   NODE(parser, IntentStmt)
   NODE(parser, InterfaceBlock)
   NODE(parser, InterfaceBody)
@@ -415,7 +415,7 @@ class ParseTreeDumper {
   NODE(parser, IoControlSpec)
   NODE(IoControlSpec, Asynchronous)
   NODE(IoControlSpec, CharExpr)
-  NODE_ENUM(IoControlSpec::CharExpr, Kind)
+  NODE_ENUM(common, IoControlCharExprKind)
   NODE(IoControlSpec, Pos)
   NODE(IoControlSpec, Rec)
   NODE(IoControlSpec, Size)
@@ -483,7 +483,7 @@ class ParseTreeDumper {
         .str();
   }
   NODE(parser, OmpCancelType)
-  NODE_ENUM(OmpCancelType, Type)
+  NODE_ENUM(common, OmpCancelKind)
   NODE(parser, OmpClause)
 #define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
 #include "llvm/Frontend/OpenMP/OMP.inc"
@@ -493,16 +493,16 @@ class ParseTreeDumper {
   NODE(parser, OmpDeclareTargetWithClause)
   NODE(parser, OmpDeclareTargetWithList)
   NODE(parser, OmpDefaultClause)
-  NODE_ENUM(OmpDefaultClause, Type)
+  NODE_ENUM(common, OmpDefaultClauseKind)
   NODE(parser, OmpDefaultmapClause)
-  NODE_ENUM(OmpDefaultmapClause, ImplicitBehavior)
-  NODE_ENUM(OmpDefaultmapClause, VariableCategory)
+  NODE_ENUM(common, OmpDefaultmapClauseImplicitBehavior)
+  NODE_ENUM(common, OmpDefaultmapClauseVariableCategory)
   NODE(parser, OmpDependClause)
   NODE(OmpDependClause, InOut)
   NODE(OmpDependClause, Sink)
   NODE(OmpDependClause, Source)
   NODE(parser, OmpDependenceType)
-  NODE_ENUM(OmpDependenceType, Type)
+  NODE_ENUM(common, OmpDependenceKind)
   NODE(parser, OmpDependSinkVec)
   NODE(parser, OmpDependSinkVecLength)
   NODE(parser, OmpEndAllocators)
@@ -512,17 +512,17 @@ class ParseTreeDumper {
   NODE(parser, OmpEndLoopDirective)
   NODE(parser, OmpEndSectionsDirective)
   NODE(parser, OmpIfClause)
-  NODE_ENUM(OmpIfClause, DirectiveNameModifier)
+  NODE_ENUM(common, OmpIfClauseDirectiveNameModifier)
   NODE(parser, OmpLinearClause)
   NODE(OmpLinearClause, WithModifier)
   NODE(OmpLinearClause, WithoutModifier)
   NODE(parser, OmpLinearModifier)
-  NODE_ENUM(OmpLinearModifier, Type)
+  NODE_ENUM(common, OmpLinearModifierKind)
   NODE(parser, OmpLoopDirective)
   NODE(parser, OmpMapClause)
   NODE(parser, OmpMapType)
   NODE(OmpMapType, Always)
-  NODE_ENUM(OmpMapType, Type)
+  NODE_ENUM(common, OmpMapKind)
   static std::string GetNodeName(const llvm::omp::Clause &x) {
     return llvm::Twine(
         "llvm::omp::Clause = ", llvm::omp::getOpenMPClauseName(x))
@@ -531,11 +531,11 @@ class ParseTreeDumper {
   NODE(parser, OmpObject)
   NODE(parser, OmpObjectList)
   NODE(parser, OmpOrderClause)
-  NODE_ENUM(OmpOrderClause, Type)
+  NODE_ENUM(common, OmpOrderClauseKind)
   NODE(parser, OmpOrderModifier)
-  NODE_ENUM(OmpOrderModifier, Kind)
+  NODE_ENUM(common, OmpOrderModifierKind)
   NODE(parser, OmpProcBindClause)
-  NODE_ENUM(OmpProcBindClause, Type)
+  NODE_ENUM(common, OmpProcBindClauseKind)
   NODE(parser, OmpReductionClause)
   NODE(parser, OmpInReductionClause)
   NODE(parser, OmpReductionCombiner)
@@ -548,16 +548,16 @@ class ParseTreeDumper {
   NODE(OmpAllocateClause::AllocateModifier, ComplexModifier)
   NODE(OmpAllocateClause::AllocateModifier, Align)
   NODE(parser, OmpScheduleClause)
-  NODE_ENUM(OmpScheduleClause, ScheduleType)
+  NODE_ENUM(common, OmpScheduleClauseKind)
   NODE(parser, OmpDeviceClause)
-  NODE_ENUM(OmpDeviceClause, DeviceModifier)
+  NODE_ENUM(common, OmpDeviceClauseDeviceModifier)
   NODE(parser, OmpDeviceTypeClause)
-  NODE_ENUM(OmpDeviceTypeClause, Type)
+  NODE_ENUM(common, OmpDeviceTypeClauseKind)
   NODE(parser, OmpScheduleModifier)
   NODE(OmpScheduleModifier, Modifier1)
   NODE(OmpScheduleModifier, Modifier2)
   NODE(parser, OmpScheduleModifierType)
-  NODE_ENUM(OmpScheduleModifierType, ModType)
+  NODE_ENUM(common, OmpScheduleModifierKind)
   NODE(parser, OmpSectionBlocks)
   NODE(parser, OmpSectionsDirective)
   NODE(parser, OmpSimpleStandaloneDirective)
@@ -589,7 +589,7 @@ class ParseTreeDumper {
   NODE(parser, OmpAtomicClause)
   NODE(parser, OmpAtomicClauseList)
   NODE(parser, OmpAtomicDefaultMemOrderClause)
-  NODE_ENUM(OmpAtomicDefaultMemOrderClause, Type)
+  NODE_ENUM(common, OmpAtomicDefaultMemOrderClauseKind)
   NODE(parser, OpenMPFlushConstruct)
   NODE(parser, OpenMPLoopConstruct)
   NODE(parser, OpenMPExecutableAllocate)
@@ -641,7 +641,7 @@ class ParseTreeDumper {
   NODE(parser, ProcedureDeclarationStmt)
   NODE(parser, ProcedureDesignator)
   NODE(parser, ProcedureStmt)
-  NODE_ENUM(ProcedureStmt, Kind)
+  NODE_ENUM(common, ProcedureKind)
   NODE(parser, Program)
   NODE(parser, ProgramStmt)
   NODE(parser, ProgramUnit)
@@ -658,7 +658,7 @@ class ParseTreeDumper {
   NODE(parser, Save)
   NODE(parser, SaveStmt)
   NODE(parser, SavedEntity)
-  NODE_ENUM(SavedEntity, Kind)
+  NODE_ENUM(common, SavedEntityKind)
   NODE(parser, SectionSubscript)
   NODE(parser, SelectCaseStmt)
   NODE(parser, SelectRankCaseStmt)
@@ -686,7 +686,7 @@ class ParseTreeDumper {
   NODE(parser, StmtFunctionStmt)
   NODE(parser, StopCode)
   NODE(parser, StopStmt)
-  NODE_ENUM(StopStmt, Kind)
+  NODE_ENUM(common, StopKind)
   NODE(parser, StructureComponent)
   NODE(parser, StructureConstructor)
   NODE(parser, StructureDef)
@@ -735,7 +735,7 @@ class ParseTreeDumper {
   NODE(parser, UnlockStmt)
   NODE(parser, UnsignedTypeSpec)
   NODE(parser, UseStmt)
-  NODE_ENUM(UseStmt, ModuleNature)
+  NODE_ENUM(common, ModuleNature)
   NODE(parser, Value)
   NODE(parser, ValueStmt)
   NODE(parser, Variable)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index d8449c8b812ae2f..9c201fa0450de1a 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -594,9 +594,7 @@ WRAPPER_CLASS(DefinedOpName, Name);
 // R610 extended-intrinsic-op -> intrinsic-operator
 struct DefinedOperator {
   UNION_CLASS_BOILERPLATE(DefinedOperator);
-  ENUM_CLASS(IntrinsicOperator, Power, Multiply, Divide, Add, Subtract, Concat,
-      LT, LE, EQ, NE, GE, GT, NOT, AND, OR, EQV, NEQV)
-  std::variant<DefinedOpName, IntrinsicOperator> u;
+  std::variant<DefinedOpName, common::IntrinsicOperator> u;
 };
 
 // R804 object-name -> name
@@ -890,8 +888,7 @@ struct LiteralConstant {
 
 // R807 access-spec -> PUBLIC | PRIVATE
 struct AccessSpec {
-  ENUM_CLASS(Kind, Public, Private)
-  WRAPPER_CLASS_BOILERPLATE(AccessSpec, Kind);
+  WRAPPER_CLASS_BOILERPLATE(AccessSpec, common::AccessSpecKind);
 };
 
 // R728 type-attr-spec ->
@@ -1335,8 +1332,7 @@ struct ArraySpec {
 
 // R826 intent-spec -> IN | OUT | INOUT
 struct IntentSpec {
-  ENUM_CLASS(Intent, In, Out, InOut)
-  WRAPPER_CLASS_BOILERPLATE(IntentSpec, Intent);
+  WRAPPER_CLASS_BOILERPLATE(IntentSpec, common::IntentSpecKind);
 };
 
 // R802 attr-spec ->
@@ -1412,8 +1408,7 @@ WRAPPER_CLASS(AsynchronousStmt, std::list<ObjectName>);
 // R833 bind-entity -> entity-name | / common-block-name /
 struct BindEntity {
   TUPLE_CLASS_BOILERPLATE(BindEntity);
-  ENUM_CLASS(Kind, Object, Common)
-  std::tuple<Kind, Name> t;
+  std::tuple<common::BindEntityKind, Name> t;
 };
 
 // R832 bind-stmt -> language-binding-spec [::] bind-entity-list
@@ -1547,8 +1542,7 @@ WRAPPER_CLASS(ProtectedStmt, std::list<Name>);
 // R858 proc-pointer-name -> name
 struct SavedEntity {
   TUPLE_CLASS_BOILERPLATE(SavedEntity);
-  ENUM_CLASS(Kind, Entity, Common)
-  std::tuple<Kind, Name> t;
+  std::tuple<common::SavedEntityKind, Name> t;
 };
 
 // R856 save-stmt -> SAVE [[::] saved-entity-list]
@@ -1581,8 +1575,8 @@ struct ImplicitSpec {
 // R866 implicit-name-spec -> EXTERNAL | TYPE
 struct ImplicitStmt {
   UNION_CLASS_BOILERPLATE(ImplicitStmt);
-  ENUM_CLASS(ImplicitNoneNameSpec, External, Type) // R866
-  std::variant<std::list<ImplicitSpec>, std::list<ImplicitNoneNameSpec>> u;
+  std::variant<std::list<ImplicitSpec>, std::list<common::ImplicitNoneNameSpec>>
+      u;
 };
 
 // R874 common-block-object -> variable-name [( array-spec )]
@@ -2481,9 +2475,10 @@ WRAPPER_CLASS(StopCode, Scalar<Expr>);
 // R1161 error-stop-stmt ->
 //         ERROR STOP [stop-code] [, QUIET = scalar-logical-expr]
 struct StopStmt {
-  ENUM_CLASS(Kind, Stop, ErrorStop)
   TUPLE_CLASS_BOILERPLATE(StopStmt);
-  std::tuple<Kind, std::optional<StopCode>, std::optional<ScalarLogicalExpr>> t;
+  std::tuple<common::StopKind, std::optional<StopCode>,
+      std::optional<ScalarLogicalExpr>>
+      t;
 };
 
 // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
@@ -2608,11 +2603,8 @@ WRAPPER_CLASS(ErrLabel, Label);
 struct ConnectSpec {
   UNION_CLASS_BOILERPLATE(ConnectSpec);
   struct CharExpr {
-    ENUM_CLASS(Kind, Access, Action, Asynchronous, Blank, Decimal, Delim,
-        Encoding, Form, Pad, Position, Round, Sign,
-        /* extensions: */ Carriagecontrol, Convert, Dispose)
     TUPLE_CLASS_BOILERPLATE(CharExpr);
-    std::tuple<Kind, ScalarDefaultCharExpr> t;
+    std::tuple<common::ConnectCharExprKind, ScalarDefaultCharExpr> t;
   };
   WRAPPER_CLASS(Recl, ScalarIntExpr);
   WRAPPER_CLASS(Newunit, ScalarIntVariable);
@@ -2666,9 +2658,8 @@ WRAPPER_CLASS(EorLabel, Label);
 struct IoControlSpec {
   UNION_CLASS_BOILERPLATE(IoControlSpec);
   struct CharExpr {
-    ENUM_CLASS(Kind, Advance, Blank, Decimal, Delim, Pad, Round, Sign)
     TUPLE_CLASS_BOILERPLATE(CharExpr);
-    std::tuple<Kind, ScalarDefaultCharExpr> t;
+    std::tuple<common::IoControlCharExprKind, ScalarDefaultCharExpr> t;
   };
   WRAPPER_CLASS(Asynchronous, ScalarDefaultCharConstantExpr);
   WRAPPER_CLASS(Pos, ScalarIntExpr);
@@ -2824,22 +2815,16 @@ WRAPPER_CLASS(FlushStmt, std::list<PositionOrFlushSpec>);
 struct InquireSpec {
   UNION_CLASS_BOILERPLATE(InquireSpec);
   struct CharVar {
-    ENUM_CLASS(Kind, Access, Action, Asynchronous, Blank, Decimal, Delim,
-        Direct, Encoding, Form, Formatted, Iomsg, Name, Pad, Position, Read,
-        Readwrite, Round, Sequential, Sign, Stream, Status, Unformatted, Write,
-        /* extensions: */ Carriagecontrol, Convert, Dispose)
     TUPLE_CLASS_BOILERPLATE(CharVar);
-    std::tuple<Kind, ScalarDefaultCharVariable> t;
+    std::tuple<common::InquireCharVarKind, ScalarDefaultCharVariable> t;
   };
   struct IntVar {
-    ENUM_CLASS(Kind, Iostat, Nextrec, Number, Pos, Recl, Size)
     TUPLE_CLASS_BOILERPLATE(IntVar);
-    std::tuple<Kind, ScalarIntVariable> t;
+    std::tuple<common::InquireIntVarKind, ScalarIntVariable> t;
   };
   struct LogVar {
-    ENUM_CLASS(Kind, Exist, Named, Opened, Pending)
     TUPLE_CLASS_BOILERPLATE(LogVar);
-    std::tuple<Kind, Scalar<Logical<Variable>>> t;
+    std::tuple<common::InquireLogVarKind, Scalar<Logical<Variable>>> t;
   };
   std::variant<FileUnitNumber, FileNameExpr, CharVar, IntVar, LogVar, IdExpr,
       ErrLabel>
@@ -3015,11 +3000,10 @@ struct Only {
 // R1410 module-nature -> INTRINSIC | NON_INTRINSIC
 struct UseStmt {
   BOILERPLATE(UseStmt);
-  ENUM_CLASS(ModuleNature, Intrinsic, Non_Intrinsic) // R1410
   template <typename A>
-  UseStmt(std::optional<ModuleNature> &&nat, Name &&n, std::list<A> &&x)
+  UseStmt(std::optional<common::ModuleNature> &&nat, Name &&n, std::list<A> &&x)
       : nature(std::move(nat)), moduleName(std::move(n)), u(std::move(x)) {}
-  std::optional<ModuleNature> nature;
+  std::optional<common::ModuleNature> nature;
   Name moduleName;
   std::variant<std::list<Rename>, std::list<Only>> u;
 };
@@ -3133,9 +3117,8 @@ struct InterfaceBody {
 
 // R1506 procedure-stmt -> [MODULE] PROCEDURE [::] specific-procedure-list
 struct ProcedureStmt {
-  ENUM_CLASS(Kind, ModuleProcedure, Procedure)
   TUPLE_CLASS_BOILERPLATE(ProcedureStmt);
-  std::tuple<Kind, std::list<Name>> t;
+  std::tuple<common::ProcedureKind, std::list<Name>> t;
 };
 
 // R1502 interface-specification -> interface-body | procedure-stmt
@@ -3379,14 +3362,12 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 
 // 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD)
 struct OmpProcBindClause {
-  ENUM_CLASS(Type, Close, Master, Spread, Primary)
-  WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, common::OmpProcBindClauseKind);
 };
 
 // 2.15.3.1 default-clause -> DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
 struct OmpDefaultClause {
-  ENUM_CLASS(Type, Private, Firstprivate, Shared, None)
-  WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, common::OmpDefaultClauseKind);
 };
 
 // 2.1 Directives or clauses may accept a list or extended-list.
@@ -3404,8 +3385,7 @@ WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
 struct OmpMapType {
   TUPLE_CLASS_BOILERPLATE(OmpMapType);
   EMPTY_CLASS(Always);
-  ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete)
-  std::tuple<std::optional<Always>, Type> t;
+  std::tuple<std::optional<Always>, common::OmpMapKind> t;
 };
 
 // 2.15.5.1 map -> MAP ([ [ALWAYS[,]] map-type : ] variable-name-list)
@@ -3417,16 +3397,15 @@ struct OmpMapClause {
 // 2.15.5.2 defaultmap -> DEFAULTMAP (implicit-behavior[:variable-category])
 struct OmpDefaultmapClause {
   TUPLE_CLASS_BOILERPLATE(OmpDefaultmapClause);
-  ENUM_CLASS(
-      ImplicitBehavior, Alloc, To, From, Tofrom, Firstprivate, None, Default)
-  ENUM_CLASS(VariableCategory, Scalar, Aggregate, Allocatable, Pointer)
-  std::tuple<ImplicitBehavior, std::optional<VariableCategory>> t;
+  std::tuple<common::OmpDefaultmapClauseImplicitBehavior,
+      std::optional<common::OmpDefaultmapClauseVariableCategory>>
+      t;
 };
 
 // 2.7.1 sched-modifier -> MONOTONIC | NONMONOTONIC | SIMD
 struct OmpScheduleModifierType {
-  ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd)
-  WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType);
+  WRAPPER_CLASS_BOILERPLATE(
+      OmpScheduleModifierType, common::OmpScheduleModifierKind);
 };
 
 struct OmpScheduleModifier {
@@ -3440,8 +3419,7 @@ struct OmpScheduleModifier {
 //                                    kind[, chunk_size])
 struct OmpScheduleClause {
   TUPLE_CLASS_BOILERPLATE(OmpScheduleClause);
-  ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime)
-  std::tuple<std::optional<OmpScheduleModifier>, ScheduleType,
+  std::tuple<std::optional<OmpScheduleModifier>, common::OmpScheduleClauseKind,
       std::optional<ScalarIntExpr>>
       t;
 };
@@ -3449,22 +3427,23 @@ struct OmpScheduleClause {
 // device([ device-modifier :] scalar-integer-expression)
 struct OmpDeviceClause {
   TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
-  ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
-  std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
+  std::tuple<std::optional<common::OmpDeviceClauseDeviceModifier>,
+      ScalarIntExpr>
+      t;
 };
 
 // device_type(any | host | nohost)
 struct OmpDeviceTypeClause {
-  ENUM_CLASS(Type, Any, Host, Nohost)
-  WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type);
+  WRAPPER_CLASS_BOILERPLATE(
+      OmpDeviceTypeClause, common::OmpDeviceTypeClauseKind);
 };
 
 // 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
 struct OmpIfClause {
   TUPLE_CLASS_BOILERPLATE(OmpIfClause);
-  ENUM_CLASS(DirectiveNameModifier, Parallel, Simd, Target, TargetData,
-      TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams)
-  std::tuple<std::optional<DirectiveNameModifier>, ScalarLogicalExpr> t;
+  std::tuple<std::optional<common::OmpIfClauseDirectiveNameModifier>,
+      ScalarLogicalExpr>
+      t;
 };
 
 // 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant])
@@ -3477,20 +3456,17 @@ struct OmpAlignedClause {
 // 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent)
 struct OmpOrderModifier {
   UNION_CLASS_BOILERPLATE(OmpOrderModifier);
-  ENUM_CLASS(Kind, Reproducible, Unconstrained)
-  std::variant<Kind> u;
+  std::variant<common::OmpOrderModifierKind> u;
 };
 
 struct OmpOrderClause {
   TUPLE_CLASS_BOILERPLATE(OmpOrderClause);
-  ENUM_CLASS(Type, Concurrent)
-  std::tuple<std::optional<OmpOrderModifier>, Type> t;
+  std::tuple<std::optional<OmpOrderModifier>, common::OmpOrderClauseKind> t;
 };
 
 // 2.15.3.7 linear-modifier -> REF | VAL | UVAL
 struct OmpLinearModifier {
-  ENUM_CLASS(Type, Ref, Val, Uval)
-  WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, common::OmpLinearModifierKind);
 };
 
 // 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step])
@@ -3572,8 +3548,7 @@ struct OmpDependSinkVec {
 
 // 2.13.9 depend-type -> IN | OUT | INOUT | SOURCE | SINK
 struct OmpDependenceType {
-  ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
-  WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, common::OmpDependenceKind);
 };
 
 // 2.13.9 depend-clause -> DEPEND (((IN | OUT | INOUT) : variable-name-list) |
@@ -3593,8 +3568,8 @@ struct OmpDependClause {
 //                 ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL |
 //                                           RELAXED)
 struct OmpAtomicDefaultMemOrderClause {
-  ENUM_CLASS(Type, SeqCst, AcqRel, Relaxed)
-  WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause,
+      common::OmpAtomicDefaultMemOrderClauseKind);
 };
 
 // OpenMP Clauses
@@ -3881,8 +3856,7 @@ struct OmpLoopDirective {
 
 // 2.14.1 construct-type-clause -> PARALLEL | SECTIONS | DO | TASKGROUP
 struct OmpCancelType {
-  ENUM_CLASS(Type, Parallel, Sections, Do, Taskgroup)
-  WRAPPER_CLASS_BOILERPLATE(OmpCancelType, Type);
+  WRAPPER_CLASS_BOILERPLATE(OmpCancelType, common::OmpCancelKind);
   CharBlock source;
 };
 
@@ -4027,8 +4001,7 @@ struct AccDefaultClause {
 };
 
 struct AccDataModifier {
-  ENUM_CLASS(Modifier, ReadOnly, Zero)
-  WRAPPER_CLASS_BOILERPLATE(AccDataModifier, Modifier);
+  WRAPPER_CLASS_BOILERPLATE(AccDataModifier, common::AccDataModifierKind);
   CharBlock source;
 };
 
@@ -4039,9 +4012,8 @@ struct AccObjectListWithModifier {
 
 // 2.5.15: + | * | max | min | iand | ior | ieor | .and. | .or. | .eqv. | .neqv.
 struct AccReductionOperator {
-  ENUM_CLASS(
-      Operator, Plus, Multiply, Max, Min, Iand, Ior, Ieor, And, Or, Eqv, Neqv)
-  WRAPPER_CLASS_BOILERPLATE(AccReductionOperator, Operator);
+  WRAPPER_CLASS_BOILERPLATE(
+      AccReductionOperator, common::AccReductionOperatorKind);
   CharBlock source;
 };
 
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index ac1fe7f68a9a665..46b5d05abfbfaa7 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -1196,50 +1196,50 @@ mlir::Value genIOOption<Fortran::parser::ConnectSpec::CharExpr>(
     mlir::Value cookie, const Fortran::parser::ConnectSpec::CharExpr &spec) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   mlir::func::FuncOp ioFunc;
-  switch (std::get<Fortran::parser::ConnectSpec::CharExpr::Kind>(spec.t)) {
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Access:
+  switch (std::get<Fortran::common::ConnectCharExprKind>(spec.t)) {
+  case Fortran::common::ConnectCharExprKind::Access:
     ioFunc = getIORuntimeFunc<mkIOKey(SetAccess)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Action:
+  case Fortran::common::ConnectCharExprKind::Action:
     ioFunc = getIORuntimeFunc<mkIOKey(SetAction)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Asynchronous:
+  case Fortran::common::ConnectCharExprKind::Asynchronous:
     ioFunc = getIORuntimeFunc<mkIOKey(SetAsynchronous)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Blank:
+  case Fortran::common::ConnectCharExprKind::Blank:
     ioFunc = getIORuntimeFunc<mkIOKey(SetBlank)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Decimal:
+  case Fortran::common::ConnectCharExprKind::Decimal:
     ioFunc = getIORuntimeFunc<mkIOKey(SetDecimal)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Delim:
+  case Fortran::common::ConnectCharExprKind::Delim:
     ioFunc = getIORuntimeFunc<mkIOKey(SetDelim)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Encoding:
+  case Fortran::common::ConnectCharExprKind::Encoding:
     ioFunc = getIORuntimeFunc<mkIOKey(SetEncoding)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Form:
+  case Fortran::common::ConnectCharExprKind::Form:
     ioFunc = getIORuntimeFunc<mkIOKey(SetForm)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Pad:
+  case Fortran::common::ConnectCharExprKind::Pad:
     ioFunc = getIORuntimeFunc<mkIOKey(SetPad)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Position:
+  case Fortran::common::ConnectCharExprKind::Position:
     ioFunc = getIORuntimeFunc<mkIOKey(SetPosition)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Round:
+  case Fortran::common::ConnectCharExprKind::Round:
     ioFunc = getIORuntimeFunc<mkIOKey(SetRound)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Sign:
+  case Fortran::common::ConnectCharExprKind::Sign:
     ioFunc = getIORuntimeFunc<mkIOKey(SetSign)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Carriagecontrol:
+  case Fortran::common::ConnectCharExprKind::Carriagecontrol:
     ioFunc = getIORuntimeFunc<mkIOKey(SetCarriagecontrol)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Convert:
+  case Fortran::common::ConnectCharExprKind::Convert:
     ioFunc = getIORuntimeFunc<mkIOKey(SetConvert)>(loc, builder);
     break;
-  case Fortran::parser::ConnectSpec::CharExpr::Kind::Dispose:
+  case Fortran::common::ConnectCharExprKind::Dispose:
     TODO(loc, "DISPOSE not part of the runtime::io interface");
   }
   Fortran::lower::StatementContext localStatementCtx;
@@ -1273,26 +1273,26 @@ mlir::Value genIOOption<Fortran::parser::IoControlSpec::CharExpr>(
     mlir::Value cookie, const Fortran::parser::IoControlSpec::CharExpr &spec) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   mlir::func::FuncOp ioFunc;
-  switch (std::get<Fortran::parser::IoControlSpec::CharExpr::Kind>(spec.t)) {
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Advance:
+  switch (std::get<Fortran::common::IoControlCharExprKind>(spec.t)) {
+  case Fortran::common::IoControlCharExprKind::Advance:
     ioFunc = getIORuntimeFunc<mkIOKey(SetAdvance)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Blank:
+  case Fortran::common::IoControlCharExprKind::Blank:
     ioFunc = getIORuntimeFunc<mkIOKey(SetBlank)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Decimal:
+  case Fortran::common::IoControlCharExprKind::Decimal:
     ioFunc = getIORuntimeFunc<mkIOKey(SetDecimal)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Delim:
+  case Fortran::common::IoControlCharExprKind::Delim:
     ioFunc = getIORuntimeFunc<mkIOKey(SetDelim)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Pad:
+  case Fortran::common::IoControlCharExprKind::Pad:
     ioFunc = getIORuntimeFunc<mkIOKey(SetPad)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Round:
+  case Fortran::common::IoControlCharExprKind::Round:
     ioFunc = getIORuntimeFunc<mkIOKey(SetRound)>(loc, builder);
     break;
-  case Fortran::parser::IoControlSpec::CharExpr::Kind::Sign:
+  case Fortran::common::IoControlCharExprKind::Sign:
     ioFunc = getIORuntimeFunc<mkIOKey(SetSign)>(loc, builder);
     break;
   }
@@ -1439,8 +1439,8 @@ ConditionSpecInfo lowerErrorSpec(Fortran::lower::AbstractConverter &converter,
               csi.ioStatExpr = Fortran::semantics::GetExpr(var);
             },
             [&](const Fortran::parser::InquireSpec::IntVar &var) {
-              if (std::get<Fortran::parser::InquireSpec::IntVar::Kind>(var.t) ==
-                  Fortran::parser::InquireSpec::IntVar::Kind::Iostat)
+              if (std::get<Fortran::common::InquireIntVarKind>(var.t) ==
+                  Fortran::common::InquireIntVarKind::Iostat)
                 csi.ioStatExpr = Fortran::semantics::GetExpr(
                     std::get<Fortran::parser::ScalarIntVariable>(var.t));
             },
@@ -1448,9 +1448,8 @@ ConditionSpecInfo lowerErrorSpec(Fortran::lower::AbstractConverter &converter,
               ioMsgExpr = Fortran::semantics::GetExpr(var);
             },
             [&](const Fortran::parser::InquireSpec::CharVar &var) {
-              if (std::get<Fortran::parser::InquireSpec::CharVar::Kind>(
-                      var.t) ==
-                  Fortran::parser::InquireSpec::CharVar::Kind::Iomsg)
+              if (std::get<Fortran::common::InquireCharVarKind>(var.t) ==
+                  Fortran::common::InquireCharVarKind::Iomsg)
                 ioMsgExpr = Fortran::semantics::GetExpr(
                     std::get<Fortran::parser::ScalarDefaultCharVariable>(
                         var.t));
@@ -2302,8 +2301,8 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::CharVar>(
     const Fortran::parser::InquireSpec::CharVar &var,
     Fortran::lower::StatementContext &stmtCtx) {
   // IOMSG is handled with exception conditions
-  if (std::get<Fortran::parser::InquireSpec::CharVar::Kind>(var.t) ==
-      Fortran::parser::InquireSpec::CharVar::Kind::Iomsg)
+  if (std::get<Fortran::common::InquireCharVarKind>(var.t) ==
+      Fortran::common::InquireCharVarKind::Iomsg)
     return {};
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   mlir::func::FuncOp specFunc =
@@ -2317,8 +2316,8 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::CharVar>(
       builder.createIntegerConstant(
           loc, specFuncTy.getInput(1),
           Fortran::runtime::io::HashInquiryKeyword(std::string{
-              Fortran::parser::InquireSpec::CharVar::EnumToString(
-                  std::get<Fortran::parser::InquireSpec::CharVar::Kind>(var.t))}
+              Fortran::common::EnumToString(
+                  std::get<Fortran::common::InquireCharVarKind>(var.t))}
                                                        .c_str())),
       builder.createConvert(loc, specFuncTy.getInput(2), fir::getBase(str)),
       builder.createConvert(loc, specFuncTy.getInput(3), fir::getLen(str))};
@@ -2332,8 +2331,8 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::IntVar>(
     const Fortran::parser::InquireSpec::IntVar &var,
     Fortran::lower::StatementContext &stmtCtx) {
   // IOSTAT is handled with exception conditions
-  if (std::get<Fortran::parser::InquireSpec::IntVar::Kind>(var.t) ==
-      Fortran::parser::InquireSpec::IntVar::Kind::Iostat)
+  if (std::get<Fortran::common::InquireIntVarKind>(var.t) ==
+      Fortran::common::InquireIntVarKind::Iostat)
     return {};
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   mlir::func::FuncOp specFunc =
@@ -2354,8 +2353,8 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::IntVar>(
       builder.createIntegerConstant(
           loc, specFuncTy.getInput(1),
           Fortran::runtime::io::HashInquiryKeyword(std::string{
-              Fortran::parser::InquireSpec::IntVar::EnumToString(
-                  std::get<Fortran::parser::InquireSpec::IntVar::Kind>(var.t))}
+              Fortran::common::EnumToString(
+                  std::get<Fortran::common::InquireIntVarKind>(var.t))}
                                                        .c_str())),
       builder.createConvert(loc, specFuncTy.getInput(2), addr),
       builder.createConvert(loc, specFuncTy.getInput(3), kind)};
@@ -2369,10 +2368,9 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::LogVar>(
     const Fortran::parser::InquireSpec::LogVar &var,
     Fortran::lower::StatementContext &stmtCtx) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
-  auto logVarKind = std::get<Fortran::parser::InquireSpec::LogVar::Kind>(var.t);
+  auto logVarKind = std::get<Fortran::common::InquireLogVarKind>(var.t);
   bool pendId =
-      idExpr &&
-      logVarKind == Fortran::parser::InquireSpec::LogVar::Kind::Pending;
+      idExpr && logVarKind == Fortran::common::InquireLogVarKind::Pending;
   mlir::func::FuncOp specFunc =
       pendId ? getIORuntimeFunc<mkIOKey(InquirePendingId)>(loc, builder)
              : getIORuntimeFunc<mkIOKey(InquireLogical)>(loc, builder);
@@ -2390,9 +2388,8 @@ mlir::Value genInquireSpec<Fortran::parser::InquireSpec::LogVar>(
   else
     args.push_back(builder.createIntegerConstant(
         loc, specFuncTy.getInput(1),
-        Fortran::runtime::io::HashInquiryKeyword(std::string{
-            Fortran::parser::InquireSpec::LogVar::EnumToString(logVarKind)}
-                                                     .c_str())));
+        Fortran::runtime::io::HashInquiryKeyword(
+            std::string{Fortran::common::EnumToString(logVarKind)}.c_str())));
   args.push_back(builder.createConvert(loc, specFuncTy.getInput(2), addr));
   auto call = builder.create<fir::CallOp>(loc, specFunc, args);
   boolRefToLogical(loc, builder, addr);
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index d6f6ae18a401167..4a850450faac7dc 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -606,7 +606,7 @@ static void genDeclareDataOperandOperationsWithModifier(
     const Clause *x, Fortran::lower::AbstractConverter &converter,
     Fortran::semantics::SemanticsContext &semanticsContext,
     Fortran::lower::StatementContext &stmtCtx,
-    Fortran::parser::AccDataModifier::Modifier mod,
+    Fortran::common::AccDataModifierKind mod,
     llvm::SmallVectorImpl<mlir::Value> &dataClauseOperands,
     const mlir::acc::DataClause clause,
     const mlir::acc::DataClause clauseWithModifier) {
@@ -830,27 +830,27 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
 static mlir::acc::ReductionOperator
 getReductionOperator(const Fortran::parser::AccReductionOperator &op) {
   switch (op.v) {
-  case Fortran::parser::AccReductionOperator::Operator::Plus:
+  case Fortran::common::AccReductionOperatorKind::Plus:
     return mlir::acc::ReductionOperator::AccAdd;
-  case Fortran::parser::AccReductionOperator::Operator::Multiply:
+  case Fortran::common::AccReductionOperatorKind::Multiply:
     return mlir::acc::ReductionOperator::AccMul;
-  case Fortran::parser::AccReductionOperator::Operator::Max:
+  case Fortran::common::AccReductionOperatorKind::Max:
     return mlir::acc::ReductionOperator::AccMax;
-  case Fortran::parser::AccReductionOperator::Operator::Min:
+  case Fortran::common::AccReductionOperatorKind::Min:
     return mlir::acc::ReductionOperator::AccMin;
-  case Fortran::parser::AccReductionOperator::Operator::Iand:
+  case Fortran::common::AccReductionOperatorKind::Iand:
     return mlir::acc::ReductionOperator::AccIand;
-  case Fortran::parser::AccReductionOperator::Operator::Ior:
+  case Fortran::common::AccReductionOperatorKind::Ior:
     return mlir::acc::ReductionOperator::AccIor;
-  case Fortran::parser::AccReductionOperator::Operator::Ieor:
+  case Fortran::common::AccReductionOperatorKind::Ieor:
     return mlir::acc::ReductionOperator::AccXor;
-  case Fortran::parser::AccReductionOperator::Operator::And:
+  case Fortran::common::AccReductionOperatorKind::And:
     return mlir::acc::ReductionOperator::AccLand;
-  case Fortran::parser::AccReductionOperator::Operator::Or:
+  case Fortran::common::AccReductionOperatorKind::Or:
     return mlir::acc::ReductionOperator::AccLor;
-  case Fortran::parser::AccReductionOperator::Operator::Eqv:
+  case Fortran::common::AccReductionOperatorKind::Eqv:
     return mlir::acc::ReductionOperator::AccEqv;
-  case Fortran::parser::AccReductionOperator::Operator::Neqv:
+  case Fortran::common::AccReductionOperatorKind::Neqv:
     return mlir::acc::ReductionOperator::AccNeqv;
   }
   llvm_unreachable("unexpected reduction operator");
@@ -1527,7 +1527,7 @@ static void genDataOperandOperationsWithModifier(
     const Clause *x, Fortran::lower::AbstractConverter &converter,
     Fortran::semantics::SemanticsContext &semanticsContext,
     Fortran::lower::StatementContext &stmtCtx,
-    Fortran::parser::AccDataModifier::Modifier mod,
+    Fortran::common::AccDataModifierKind mod,
     llvm::SmallVectorImpl<mlir::Value> &dataClauseOperands,
     const mlir::acc::DataClause clause,
     const mlir::acc::DataClause clauseWithModifier,
@@ -1662,8 +1662,8 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CopyinOp,
                                            Fortran::parser::AccClause::Copyin>(
           copyinClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::ReadOnly,
-          dataClauseOperands, mlir::acc::DataClause::acc_copyin,
+          Fortran::common::AccDataModifierKind::ReadOnly, dataClauseOperands,
+          mlir::acc::DataClause::acc_copyin,
           mlir::acc::DataClause::acc_copyin_readonly);
     } else if (const auto *copyoutClause =
                    std::get_if<Fortran::parser::AccClause::Copyout>(
@@ -1672,8 +1672,8 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CreateOp,
                                            Fortran::parser::AccClause::Copyout>(
           copyoutClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::ReadOnly,
-          dataClauseOperands, mlir::acc::DataClause::acc_copyout,
+          Fortran::common::AccDataModifierKind::ReadOnly, dataClauseOperands,
+          mlir::acc::DataClause::acc_copyout,
           mlir::acc::DataClause::acc_copyout_zero);
       copyoutEntryOperands.append(dataClauseOperands.begin() + crtDataStart,
                                   dataClauseOperands.end());
@@ -1683,7 +1683,7 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CreateOp,
                                            Fortran::parser::AccClause::Create>(
           createClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::Zero, dataClauseOperands,
+          Fortran::common::AccDataModifierKind::Zero, dataClauseOperands,
           mlir::acc::DataClause::acc_create,
           mlir::acc::DataClause::acc_create_zero);
       createEntryOperands.append(dataClauseOperands.begin() + crtDataStart,
@@ -1856,8 +1856,8 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CopyinOp,
                                            Fortran::parser::AccClause::Copyin>(
           copyinClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::ReadOnly,
-          dataClauseOperands, mlir::acc::DataClause::acc_copyin,
+          Fortran::common::AccDataModifierKind::ReadOnly, dataClauseOperands,
+          mlir::acc::DataClause::acc_copyin,
           mlir::acc::DataClause::acc_copyin_readonly);
     } else if (const auto *copyoutClause =
                    std::get_if<Fortran::parser::AccClause::Copyout>(
@@ -1866,7 +1866,7 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CreateOp,
                                            Fortran::parser::AccClause::Copyout>(
           copyoutClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::Zero, dataClauseOperands,
+          Fortran::common::AccDataModifierKind::Zero, dataClauseOperands,
           mlir::acc::DataClause::acc_copyout,
           mlir::acc::DataClause::acc_copyout_zero);
       copyoutEntryOperands.append(dataClauseOperands.begin() + crtDataStart,
@@ -1877,7 +1877,7 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
       genDataOperandOperationsWithModifier<mlir::acc::CreateOp,
                                            Fortran::parser::AccClause::Create>(
           createClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::Zero, dataClauseOperands,
+          Fortran::common::AccDataModifierKind::Zero, dataClauseOperands,
           mlir::acc::DataClause::acc_create,
           mlir::acc::DataClause::acc_create_zero);
       createEntryOperands.append(dataClauseOperands.begin() + crtDataStart,
@@ -2147,7 +2147,7 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
               listWithModifier.t);
       mlir::acc::DataClause clause = mlir::acc::DataClause::acc_create;
       if (modifier &&
-          (*modifier).v == Fortran::parser::AccDataModifier::Modifier::Zero)
+          (*modifier).v == Fortran::common::AccDataModifierKind::Zero)
         clause = mlir::acc::DataClause::acc_create_zero;
       genDataOperandOperations<mlir::acc::CreateOp>(
           accObjectList, converter, semanticsContext, stmtCtx,
@@ -2761,7 +2761,7 @@ template <typename Clause, typename EntryOp, typename ExitOp>
 static void
 genGlobalCtorsWithModifier(Fortran::lower::AbstractConverter &converter,
                            mlir::OpBuilder &modBuilder, const Clause *x,
-                           Fortran::parser::AccDataModifier::Modifier mod,
+                           Fortran::common::AccDataModifierKind mod,
                            const mlir::acc::DataClause clause,
                            const mlir::acc::DataClause clauseWithModifier) {
   const Fortran::parser::AccObjectListWithModifier &listWithModifier = x->v;
@@ -2832,8 +2832,8 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter,
       genDeclareDataOperandOperationsWithModifier<mlir::acc::CopyinOp,
                                                   mlir::acc::DeleteOp>(
           copyinClause, converter, semanticsContext, stmtCtx,
-          Fortran::parser::AccDataModifier::Modifier::ReadOnly,
-          dataClauseOperands, mlir::acc::DataClause::acc_copyin,
+          Fortran::common::AccDataModifierKind::ReadOnly, dataClauseOperands,
+          mlir::acc::DataClause::acc_copyin,
           mlir::acc::DataClause::acc_copyin_readonly);
     } else if (const auto *copyoutClause =
                    std::get_if<Fortran::parser::AccClause::Copyout>(
@@ -2935,7 +2935,7 @@ genDeclareInModule(Fortran::lower::AbstractConverter &converter,
       genGlobalCtorsWithModifier<Fortran::parser::AccClause::Copyin,
                                  mlir::acc::CopyinOp, mlir::acc::CopyinOp>(
           converter, modBuilder, copyinClause,
-          Fortran::parser::AccDataModifier::Modifier::ReadOnly,
+          Fortran::common::AccDataModifierKind::ReadOnly,
           mlir::acc::DataClause::acc_copyin,
           mlir::acc::DataClause::acc_copyin_readonly);
     } else if (const auto *deviceResidentClause =
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 9cb370e6130dc2e..fdb6cf5c87f3f41 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -405,11 +405,10 @@ void DataSharingProcessor::collectDefaultSymbols() {
   for (const Fortran::parser::OmpClause &clause : opClauseList.v) {
     if (const auto &defaultClause =
             std::get_if<Fortran::parser::OmpClause::Default>(&clause.u)) {
-      if (defaultClause->v.v ==
-          Fortran::parser::OmpDefaultClause::Type::Private)
+      if (defaultClause->v.v == Fortran::common::OmpDefaultClauseKind::Private)
         collectSymbols(Fortran::semantics::Symbol::Flag::OmpPrivate);
       else if (defaultClause->v.v ==
-               Fortran::parser::OmpDefaultClause::Type::Firstprivate)
+               Fortran::common::OmpDefaultClauseKind::Firstprivate)
         collectSymbols(Fortran::semantics::Symbol::Flag::OmpFirstPrivate);
     }
   }
@@ -526,7 +525,7 @@ class ClauseProcessor {
                      llvm::SmallVectorImpl<mlir::Value> &dependOperands) const;
   bool
   processIf(Fortran::lower::StatementContext &stmtCtx,
-            Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName,
+            Fortran::common::OmpIfClauseDirectiveNameModifier directiveName,
             mlir::Value &result) const;
   bool
   processLink(llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const;
@@ -641,25 +640,25 @@ static std::string getReductionName(llvm::StringRef name, mlir::Type ty) {
       .str();
 }
 
-static std::string getReductionName(
-    Fortran::parser::DefinedOperator::IntrinsicOperator intrinsicOp,
-    mlir::Type ty) {
+static std::string
+getReductionName(Fortran::common::IntrinsicOperator intrinsicOp,
+                 mlir::Type ty) {
   std::string reductionName;
 
   switch (intrinsicOp) {
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::Add:
+  case Fortran::common::IntrinsicOperator::Add:
     reductionName = "add_reduction";
     break;
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::Multiply:
+  case Fortran::common::IntrinsicOperator::Multiply:
     reductionName = "multiply_reduction";
     break;
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::AND:
+  case Fortran::common::IntrinsicOperator::AND:
     return "and_reduction";
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::EQV:
+  case Fortran::common::IntrinsicOperator::EQV:
     return "eqv_reduction";
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::OR:
+  case Fortran::common::IntrinsicOperator::OR:
     return "or_reduction";
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::NEQV:
+  case Fortran::common::IntrinsicOperator::NEQV:
     return "neqv_reduction";
   default:
     reductionName = "other_reduction";
@@ -830,10 +829,10 @@ createReductionDecl(fir::FirOpBuilder &builder, llvm::StringRef reductionOpName,
 /// symbol table. The declaration has a constant initializer with the neutral
 /// value `initValue`, and the reduction combiner carried over from `reduce`.
 /// TODO: Generalize this for non-integer types, add atomic region.
-static mlir::omp::ReductionDeclareOp createReductionDecl(
-    fir::FirOpBuilder &builder, llvm::StringRef reductionOpName,
-    Fortran::parser::DefinedOperator::IntrinsicOperator intrinsicOp,
-    mlir::Type type, mlir::Location loc) {
+static mlir::omp::ReductionDeclareOp
+createReductionDecl(fir::FirOpBuilder &builder, llvm::StringRef reductionOpName,
+                    Fortran::common::IntrinsicOperator intrinsicOp,
+                    mlir::Type type, mlir::Location loc) {
   mlir::OpBuilder::InsertionGuard guard(builder);
   mlir::ModuleOp module = builder.getModule();
 
@@ -849,17 +848,17 @@ static mlir::omp::ReductionDeclareOp createReductionDecl(
 
   mlir::Value reductionOp;
   switch (intrinsicOp) {
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::Add:
+  case Fortran::common::IntrinsicOperator::Add:
     reductionOp =
         getReductionOperation<mlir::arith::AddFOp, mlir::arith::AddIOp>(
             builder, type, loc, op1, op2);
     break;
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::Multiply:
+  case Fortran::common::IntrinsicOperator::Multiply:
     reductionOp =
         getReductionOperation<mlir::arith::MulFOp, mlir::arith::MulIOp>(
             builder, type, loc, op1, op2);
     break;
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::AND: {
+  case Fortran::common::IntrinsicOperator::AND: {
     mlir::Value op1I1 = builder.createConvert(loc, builder.getI1Type(), op1);
     mlir::Value op2I1 = builder.createConvert(loc, builder.getI1Type(), op2);
 
@@ -868,7 +867,7 @@ static mlir::omp::ReductionDeclareOp createReductionDecl(
     reductionOp = builder.createConvert(loc, type, andiOp);
     break;
   }
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::OR: {
+  case Fortran::common::IntrinsicOperator::OR: {
     mlir::Value op1I1 = builder.createConvert(loc, builder.getI1Type(), op1);
     mlir::Value op2I1 = builder.createConvert(loc, builder.getI1Type(), op2);
 
@@ -877,7 +876,7 @@ static mlir::omp::ReductionDeclareOp createReductionDecl(
     reductionOp = builder.createConvert(loc, type, oriOp);
     break;
   }
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::EQV: {
+  case Fortran::common::IntrinsicOperator::EQV: {
     mlir::Value op1I1 = builder.createConvert(loc, builder.getI1Type(), op1);
     mlir::Value op2I1 = builder.createConvert(loc, builder.getI1Type(), op2);
 
@@ -887,7 +886,7 @@ static mlir::omp::ReductionDeclareOp createReductionDecl(
     reductionOp = builder.createConvert(loc, type, cmpiOp);
     break;
   }
-  case Fortran::parser::DefinedOperator::IntrinsicOperator::NEQV: {
+  case Fortran::common::IntrinsicOperator::NEQV: {
     mlir::Value op1I1 = builder.createConvert(loc, builder.getI1Type(), op1);
     mlir::Value op2I1 = builder.createConvert(loc, builder.getI1Type(), op2);
 
@@ -908,11 +907,11 @@ static mlir::omp::ReductionDeclareOp createReductionDecl(
 static mlir::omp::ScheduleModifier
 translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) {
   switch (m.v) {
-  case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic:
+  case Fortran::common::OmpScheduleModifierKind::Monotonic:
     return mlir::omp::ScheduleModifier::monotonic;
-  case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic:
+  case Fortran::common::OmpScheduleModifierKind::Nonmonotonic:
     return mlir::omp::ScheduleModifier::nonmonotonic;
-  case Fortran::parser::OmpScheduleModifierType::ModType::Simd:
+  case Fortran::common::OmpScheduleModifierKind::Simd:
     return mlir::omp::ScheduleModifier::simd;
   }
   return mlir::omp::ScheduleModifier::none;
@@ -928,14 +927,12 @@ getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) {
   if (modifier) {
     const auto &modType1 =
         std::get<Fortran::parser::OmpScheduleModifier::Modifier1>(modifier->t);
-    if (modType1.v.v ==
-        Fortran::parser::OmpScheduleModifierType::ModType::Simd) {
+    if (modType1.v.v == Fortran::common::OmpScheduleModifierKind::Simd) {
       const auto &modType2 = std::get<
           std::optional<Fortran::parser::OmpScheduleModifier::Modifier2>>(
           modifier->t);
       if (modType2 &&
-          modType2->v.v !=
-              Fortran::parser::OmpScheduleModifierType::ModType::Simd)
+          modType2->v.v != Fortran::common::OmpScheduleModifierKind::Simd)
         return translateScheduleModifier(modType2->v);
 
       return mlir::omp::ScheduleModifier::none;
@@ -956,14 +953,14 @@ getSimdModifier(const Fortran::parser::OmpScheduleClause &x) {
   if (modifier) {
     const auto &modType1 =
         std::get<Fortran::parser::OmpScheduleModifier::Modifier1>(modifier->t);
-    if (modType1.v.v == Fortran::parser::OmpScheduleModifierType::ModType::Simd)
+    if (modType1.v.v == Fortran::common::OmpScheduleModifierKind::Simd)
       return mlir::omp::ScheduleModifier::simd;
 
     const auto &modType2 = std::get<
         std::optional<Fortran::parser::OmpScheduleModifier::Modifier2>>(
         modifier->t);
-    if (modType2 && modType2->v.v ==
-                        Fortran::parser::OmpScheduleModifierType::ModType::Simd)
+    if (modType2 &&
+        modType2->v.v == Fortran::common::OmpScheduleModifierKind::Simd)
       return mlir::omp::ScheduleModifier::simd;
   }
   return mlir::omp::ScheduleModifier::none;
@@ -1022,16 +1019,16 @@ static mlir::omp::ClauseProcBindKindAttr genProcBindKindAttr(
     const Fortran::parser::OmpClause::ProcBind *procBindClause) {
   mlir::omp::ClauseProcBindKind procBindKind;
   switch (procBindClause->v.v) {
-  case Fortran::parser::OmpProcBindClause::Type::Master:
+  case Fortran::common::OmpProcBindClauseKind::Master:
     procBindKind = mlir::omp::ClauseProcBindKind::Master;
     break;
-  case Fortran::parser::OmpProcBindClause::Type::Close:
+  case Fortran::common::OmpProcBindClauseKind::Close:
     procBindKind = mlir::omp::ClauseProcBindKind::Close;
     break;
-  case Fortran::parser::OmpProcBindClause::Type::Spread:
+  case Fortran::common::OmpProcBindClauseKind::Spread:
     procBindKind = mlir::omp::ClauseProcBindKind::Spread;
     break;
-  case Fortran::parser::OmpProcBindClause::Type::Primary:
+  case Fortran::common::OmpProcBindClauseKind::Primary:
     procBindKind = mlir::omp::ClauseProcBindKind::Primary;
     break;
   }
@@ -1048,13 +1045,13 @@ genDependKindAttr(fir::FirOpBuilder &firOpBuilder,
           std::get<Fortran::parser::OmpDependClause::InOut>(dependClause->v.u)
               .t)
           .v) {
-  case Fortran::parser::OmpDependenceType::Type::In:
+  case Fortran::common::OmpDependenceKind::In:
     pbKind = mlir::omp::ClauseTaskDepend::taskdependin;
     break;
-  case Fortran::parser::OmpDependenceType::Type::Out:
+  case Fortran::common::OmpDependenceKind::Out:
     pbKind = mlir::omp::ClauseTaskDepend::taskdependout;
     break;
-  case Fortran::parser::OmpDependenceType::Type::Inout:
+  case Fortran::common::OmpDependenceKind::Inout:
     pbKind = mlir::omp::ClauseTaskDepend::taskdependinout;
     break;
   default:
@@ -1069,11 +1066,11 @@ static mlir::Value getIfClauseOperand(
     Fortran::lower::AbstractConverter &converter,
     Fortran::lower::StatementContext &stmtCtx,
     const Fortran::parser::OmpClause::If *ifClause,
-    Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName,
+    Fortran::common::OmpIfClauseDirectiveNameModifier directiveName,
     mlir::Location clauseLocation) {
   // Only consider the clause if it's intended for the given directive.
   auto &directive = std::get<
-      std::optional<Fortran::parser::OmpIfClause::DirectiveNameModifier>>(
+      std::optional<Fortran::common::OmpIfClauseDirectiveNameModifier>>(
       ifClause->v.t);
   if (directive && directive.value() != directiveName)
     return nullptr;
@@ -1102,15 +1099,14 @@ addReductionDecl(mlir::Location currentLocation,
   if (const auto &redDefinedOp =
           std::get_if<Fortran::parser::DefinedOperator>(&redOperator.u)) {
     const auto &intrinsicOp{
-        std::get<Fortran::parser::DefinedOperator::IntrinsicOperator>(
-            redDefinedOp->u)};
+        std::get<Fortran::common::IntrinsicOperator>(redDefinedOp->u)};
     switch (intrinsicOp) {
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::Add:
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::Multiply:
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::AND:
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::EQV:
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::OR:
-    case Fortran::parser::DefinedOperator::IntrinsicOperator::NEQV:
+    case Fortran::common::IntrinsicOperator::Add:
+    case Fortran::common::IntrinsicOperator::Multiply:
+    case Fortran::common::IntrinsicOperator::AND:
+    case Fortran::common::IntrinsicOperator::EQV:
+    case Fortran::common::IntrinsicOperator::OR:
+    case Fortran::common::IntrinsicOperator::NEQV:
       break;
 
     default:
@@ -1264,16 +1260,16 @@ bool ClauseProcessor::processDefault() const {
   if (auto *defaultClause = findUniqueClause<ClauseTy::Default>()) {
     // Private, Firstprivate, Shared, None
     switch (defaultClause->v.v) {
-    case Fortran::parser::OmpDefaultClause::Type::Shared:
-    case Fortran::parser::OmpDefaultClause::Type::None:
+    case Fortran::common::OmpDefaultClauseKind::Shared:
+    case Fortran::common::OmpDefaultClauseKind::None:
       // Default clause with shared or none do not require any handling since
       // Shared is the default behavior in the IR and None is only required
       // for semantic checks.
       break;
-    case Fortran::parser::OmpDefaultClause::Type::Private:
+    case Fortran::common::OmpDefaultClauseKind::Private:
       // TODO Support default(private)
       break;
-    case Fortran::parser::OmpDefaultClause::Type::Firstprivate:
+    case Fortran::common::OmpDefaultClauseKind::Firstprivate:
       // TODO Support default(firstprivate)
       break;
     }
@@ -1288,10 +1284,10 @@ bool ClauseProcessor::processDevice(Fortran::lower::StatementContext &stmtCtx,
   if (auto *deviceClause = findUniqueClause<ClauseTy::Device>(&source)) {
     mlir::Location clauseLocation = converter.genLocation(*source);
     if (auto deviceModifier = std::get<
-            std::optional<Fortran::parser::OmpDeviceClause::DeviceModifier>>(
+            std::optional<Fortran::common::OmpDeviceClauseDeviceModifier>>(
             deviceClause->v.t)) {
       if (deviceModifier ==
-          Fortran::parser::OmpDeviceClause::DeviceModifier::Ancestor) {
+          Fortran::common::OmpDeviceClauseDeviceModifier::Ancestor) {
         TODO(clauseLocation, "OMPD_target Device Modifier Ancestor");
       }
     }
@@ -1309,13 +1305,13 @@ bool ClauseProcessor::processDeviceType(
   if (auto *deviceTypeClause = findUniqueClause<ClauseTy::DeviceType>()) {
     // Case: declare target ... device_type(any | host | nohost)
     switch (deviceTypeClause->v.v) {
-    case Fortran::parser::OmpDeviceTypeClause::Type::Nohost:
+    case Fortran::common::OmpDeviceTypeClauseKind::Nohost:
       result = mlir::omp::DeclareTargetDeviceType::nohost;
       break;
-    case Fortran::parser::OmpDeviceTypeClause::Type::Host:
+    case Fortran::common::OmpDeviceTypeClauseKind::Host:
       result = mlir::omp::DeclareTargetDeviceType::host;
       break;
-    case Fortran::parser::OmpDeviceTypeClause::Type::Any:
+    case Fortran::common::OmpDeviceTypeClauseKind::Any:
       result = mlir::omp::DeclareTargetDeviceType::any;
       break;
     }
@@ -1437,24 +1433,23 @@ bool ClauseProcessor::processSchedule(
     mlir::MLIRContext *context = firOpBuilder.getContext();
     const Fortran::parser::OmpScheduleClause &scheduleType = scheduleClause->v;
     const auto &scheduleClauseKind =
-        std::get<Fortran::parser::OmpScheduleClause::ScheduleType>(
-            scheduleType.t);
+        std::get<Fortran::common::OmpScheduleClauseKind>(scheduleType.t);
 
     mlir::omp::ClauseScheduleKind scheduleKind;
     switch (scheduleClauseKind) {
-    case Fortran::parser::OmpScheduleClause::ScheduleType::Static:
+    case Fortran::common::OmpScheduleClauseKind::Static:
       scheduleKind = mlir::omp::ClauseScheduleKind::Static;
       break;
-    case Fortran::parser::OmpScheduleClause::ScheduleType::Dynamic:
+    case Fortran::common::OmpScheduleClauseKind::Dynamic:
       scheduleKind = mlir::omp::ClauseScheduleKind::Dynamic;
       break;
-    case Fortran::parser::OmpScheduleClause::ScheduleType::Guided:
+    case Fortran::common::OmpScheduleClauseKind::Guided:
       scheduleKind = mlir::omp::ClauseScheduleKind::Guided;
       break;
-    case Fortran::parser::OmpScheduleClause::ScheduleType::Auto:
+    case Fortran::common::OmpScheduleClauseKind::Auto:
       scheduleKind = mlir::omp::ClauseScheduleKind::Auto;
       break;
-    case Fortran::parser::OmpScheduleClause::ScheduleType::Runtime:
+    case Fortran::common::OmpScheduleClauseKind::Runtime:
       scheduleKind = mlir::omp::ClauseScheduleKind::Runtime;
       break;
     }
@@ -1620,7 +1615,7 @@ bool ClauseProcessor::processDepend(
 
 bool ClauseProcessor::processIf(
     Fortran::lower::StatementContext &stmtCtx,
-    Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName,
+    Fortran::common::OmpIfClauseDirectiveNameModifier directiveName,
     mlir::Value &result) const {
   bool found = false;
   findRepeatableClause<ClauseTy::If>(
@@ -1665,27 +1660,27 @@ bool ClauseProcessor::processMap(
         llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
     // If the map type is specified, then process it else Tofrom is the default.
     if (oMapType) {
-      const Fortran::parser::OmpMapType::Type &mapType =
-          std::get<Fortran::parser::OmpMapType::Type>(oMapType->t);
+      const Fortran::common::OmpMapKind &mapType =
+          std::get<Fortran::common::OmpMapKind>(oMapType->t);
       switch (mapType) {
-      case Fortran::parser::OmpMapType::Type::To:
+      case Fortran::common::OmpMapKind::To:
         mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
         break;
-      case Fortran::parser::OmpMapType::Type::From:
+      case Fortran::common::OmpMapKind::From:
         mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
         break;
-      case Fortran::parser::OmpMapType::Type::Tofrom:
+      case Fortran::common::OmpMapKind::Tofrom:
         mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO |
                        llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
         break;
-      case Fortran::parser::OmpMapType::Type::Alloc:
-      case Fortran::parser::OmpMapType::Type::Release:
+      case Fortran::common::OmpMapKind::Alloc:
+      case Fortran::common::OmpMapKind::Release:
         // alloc and release is the default map_type for the Target Data Ops,
         // i.e. if no bits for map_type is supplied then alloc/release is
         // implicitly assumed based on the target directive. Default value for
         // Target Data and Enter Data is alloc and for Exit Data it is release.
         break;
-      case Fortran::parser::OmpMapType::Type::Delete:
+      case Fortran::common::OmpMapKind::Delete:
         mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE;
       }
 
@@ -2213,7 +2208,7 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
 
   ClauseProcessor cp(converter, clauseList);
   cp.processIf(stmtCtx,
-               Fortran::parser::OmpIfClause::DirectiveNameModifier::Parallel,
+               Fortran::common::OmpIfClauseDirectiveNameModifier::Parallel,
                ifClauseOperand);
   cp.processNumThreads(stmtCtx, numThreadsClauseOperand);
   cp.processProcBind(procBindKindAttr);
@@ -2266,8 +2261,7 @@ genTaskOp(Fortran::lower::AbstractConverter &converter,
       dependOperands;
 
   ClauseProcessor cp(converter, clauseList);
-  cp.processIf(stmtCtx,
-               Fortran::parser::OmpIfClause::DirectiveNameModifier::Task,
+  cp.processIf(stmtCtx, Fortran::common::OmpIfClauseDirectiveNameModifier::Task,
                ifClauseOperand);
   cp.processAllocate(allocatorOperands, allocateOperands);
   cp.processDefault();
@@ -2325,7 +2319,7 @@ genDataOp(Fortran::lower::AbstractConverter &converter,
 
   ClauseProcessor cp(converter, clauseList);
   cp.processIf(stmtCtx,
-               Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetData,
+               Fortran::common::OmpIfClauseDirectiveNameModifier::TargetData,
                ifClauseOperand);
   cp.processDevice(stmtCtx, deviceOperand);
   cp.processUseDevicePtr(devicePtrOperands, useDeviceTypes, useDeviceLocs,
@@ -2359,15 +2353,15 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter,
   llvm::SmallVector<mlir::Value> mapOperands;
   llvm::SmallVector<mlir::IntegerAttr> mapTypes;
 
-  Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName;
+  Fortran::common::OmpIfClauseDirectiveNameModifier directiveName;
   llvm::omp::Directive directive;
   if constexpr (std::is_same_v<OpTy, mlir::omp::EnterDataOp>) {
     directiveName =
-        Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetEnterData;
+        Fortran::common::OmpIfClauseDirectiveNameModifier::TargetEnterData;
     directive = llvm::omp::Directive::OMPD_target_enter_data;
   } else if constexpr (std::is_same_v<OpTy, mlir::omp::ExitDataOp>) {
     directiveName =
-        Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetExitData;
+        Fortran::common::OmpIfClauseDirectiveNameModifier::TargetExitData;
     directive = llvm::omp::Directive::OMPD_target_exit_data;
   } else {
     return nullptr;
@@ -2406,7 +2400,7 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
 
   ClauseProcessor cp(converter, clauseList);
   cp.processIf(stmtCtx,
-               Fortran::parser::OmpIfClause::DirectiveNameModifier::Target,
+               Fortran::common::OmpIfClauseDirectiveNameModifier::Target,
                ifClauseOperand);
   cp.processDevice(stmtCtx, deviceOperand);
   cp.processThreadLimit(stmtCtx, threadLimitOperand);
@@ -2449,7 +2443,7 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter,
 
   ClauseProcessor cp(converter, clauseList);
   cp.processIf(stmtCtx,
-               Fortran::parser::OmpIfClause::DirectiveNameModifier::Teams,
+               Fortran::common::OmpIfClauseDirectiveNameModifier::Teams,
                ifClauseOperand);
   cp.processAllocate(allocatorOperands, allocateOperands);
   cp.processDefault();
@@ -2656,7 +2650,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
     mlir::Value ifClauseOperand;
     mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
     cp.processIf(stmtCtx,
-                 Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd,
+                 Fortran::common::OmpIfClauseDirectiveNameModifier::Simd,
                  ifClauseOperand);
     cp.processSimdlen(simdlenClauseOperand);
     cp.processSafelen(safelenClauseOperand);
@@ -3721,16 +3715,15 @@ void Fortran::lower::genOpenMPReduction(
       if (const auto *reductionOp =
               std::get_if<Fortran::parser::DefinedOperator>(&redOperator.u)) {
         const auto &intrinsicOp{
-            std::get<Fortran::parser::DefinedOperator::IntrinsicOperator>(
-                reductionOp->u)};
+            std::get<Fortran::common::IntrinsicOperator>(reductionOp->u)};
 
         switch (intrinsicOp) {
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::Add:
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::Multiply:
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::AND:
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::EQV:
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::OR:
-        case Fortran::parser::DefinedOperator::IntrinsicOperator::NEQV:
+        case Fortran::common::IntrinsicOperator::Add:
+        case Fortran::common::IntrinsicOperator::Multiply:
+        case Fortran::common::IntrinsicOperator::AND:
+        case Fortran::common::IntrinsicOperator::EQV:
+        case Fortran::common::IntrinsicOperator::OR:
+        case Fortran::common::IntrinsicOperator::NEQV:
           break;
         default:
           continue;
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index 11cb56c72d75932..2b94a89baea89c5 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -94,8 +94,8 @@ void Fortran::lower::genStopStatement(
   }
 
   // Second operand indicates ERROR STOP
-  bool isError = std::get<Fortran::parser::StopStmt::Kind>(stmt.t) ==
-                 Fortran::parser::StopStmt::Kind::ErrorStop;
+  bool isError = std::get<Fortran::common::StopKind>(stmt.t) ==
+                 Fortran::common::StopKind::ErrorStop;
   operands.push_back(builder.createIntegerConstant(
       loc, calleeType.getInput(operands.size()), isError));
 
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index d7e01c924c6b32c..d30452e1b47c869 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -53,46 +53,45 @@ TYPE_PARSER(space >> sourced(rawName >> construct<Name>()))
 // R610 extended-intrinsic-op -> intrinsic-operator
 // These parsers must be ordered carefully to avoid misrecognition.
 constexpr auto namedIntrinsicOperator{
-    ".LT." >> pure(DefinedOperator::IntrinsicOperator::LT) ||
-    ".LE." >> pure(DefinedOperator::IntrinsicOperator::LE) ||
-    ".EQ." >> pure(DefinedOperator::IntrinsicOperator::EQ) ||
-    ".NE." >> pure(DefinedOperator::IntrinsicOperator::NE) ||
-    ".GE." >> pure(DefinedOperator::IntrinsicOperator::GE) ||
-    ".GT." >> pure(DefinedOperator::IntrinsicOperator::GT) ||
-    ".NOT." >> pure(DefinedOperator::IntrinsicOperator::NOT) ||
-    ".AND." >> pure(DefinedOperator::IntrinsicOperator::AND) ||
-    ".OR." >> pure(DefinedOperator::IntrinsicOperator::OR) ||
-    ".EQV." >> pure(DefinedOperator::IntrinsicOperator::EQV) ||
-    ".NEQV." >> pure(DefinedOperator::IntrinsicOperator::NEQV) ||
+    ".LT." >> pure(common::IntrinsicOperator::LT) ||
+    ".LE." >> pure(common::IntrinsicOperator::LE) ||
+    ".EQ." >> pure(common::IntrinsicOperator::EQ) ||
+    ".NE." >> pure(common::IntrinsicOperator::NE) ||
+    ".GE." >> pure(common::IntrinsicOperator::GE) ||
+    ".GT." >> pure(common::IntrinsicOperator::GT) ||
+    ".NOT." >> pure(common::IntrinsicOperator::NOT) ||
+    ".AND." >> pure(common::IntrinsicOperator::AND) ||
+    ".OR." >> pure(common::IntrinsicOperator::OR) ||
+    ".EQV." >> pure(common::IntrinsicOperator::EQV) ||
+    ".NEQV." >> pure(common::IntrinsicOperator::NEQV) ||
     extension<LanguageFeature::XOROperator>(
         "nonstandard usage: .XOR. spelling of .NEQV."_port_en_US,
-        ".XOR." >> pure(DefinedOperator::IntrinsicOperator::NEQV)) ||
+        ".XOR." >> pure(common::IntrinsicOperator::NEQV)) ||
     extension<LanguageFeature::LogicalAbbreviations>(
         "nonstandard usage: abbreviated logical operator"_port_en_US,
-        ".N." >> pure(DefinedOperator::IntrinsicOperator::NOT) ||
-            ".A." >> pure(DefinedOperator::IntrinsicOperator::AND) ||
-            ".O." >> pure(DefinedOperator::IntrinsicOperator::OR) ||
+        ".N." >> pure(common::IntrinsicOperator::NOT) ||
+            ".A." >> pure(common::IntrinsicOperator::AND) ||
+            ".O." >> pure(common::IntrinsicOperator::OR) ||
             extension<LanguageFeature::XOROperator>(
                 "nonstandard usage: .X. spelling of .NEQV."_port_en_US,
-                ".X." >> pure(DefinedOperator::IntrinsicOperator::NEQV)))};
+                ".X." >> pure(common::IntrinsicOperator::NEQV)))};
 
 constexpr auto intrinsicOperator{
-    "**" >> pure(DefinedOperator::IntrinsicOperator::Power) ||
-    "*" >> pure(DefinedOperator::IntrinsicOperator::Multiply) ||
-    "//" >> pure(DefinedOperator::IntrinsicOperator::Concat) ||
-    "/=" >> pure(DefinedOperator::IntrinsicOperator::NE) ||
-    "/" >> pure(DefinedOperator::IntrinsicOperator::Divide) ||
-    "+" >> pure(DefinedOperator::IntrinsicOperator::Add) ||
-    "-" >> pure(DefinedOperator::IntrinsicOperator::Subtract) ||
-    "<=" >> pure(DefinedOperator::IntrinsicOperator::LE) ||
+    "**" >> pure(common::IntrinsicOperator::Power) ||
+    "*" >> pure(common::IntrinsicOperator::Multiply) ||
+    "//" >> pure(common::IntrinsicOperator::Concat) ||
+    "/=" >> pure(common::IntrinsicOperator::NE) ||
+    "/" >> pure(common::IntrinsicOperator::Divide) ||
+    "+" >> pure(common::IntrinsicOperator::Add) ||
+    "-" >> pure(common::IntrinsicOperator::Subtract) ||
+    "<=" >> pure(common::IntrinsicOperator::LE) ||
     extension<LanguageFeature::AlternativeNE>(
         "nonstandard usage: <> spelling of /= or .NE."_port_en_US,
-        "<>" >> pure(DefinedOperator::IntrinsicOperator::NE)) ||
-    "<" >> pure(DefinedOperator::IntrinsicOperator::LT) ||
-    "==" >> pure(DefinedOperator::IntrinsicOperator::EQ) ||
-    ">=" >> pure(DefinedOperator::IntrinsicOperator::GE) ||
-    ">" >> pure(DefinedOperator::IntrinsicOperator::GT) ||
-    namedIntrinsicOperator};
+        "<>" >> pure(common::IntrinsicOperator::NE)) ||
+    "<" >> pure(common::IntrinsicOperator::LT) ||
+    "==" >> pure(common::IntrinsicOperator::EQ) ||
+    ">=" >> pure(common::IntrinsicOperator::GE) ||
+    ">" >> pure(common::IntrinsicOperator::GT) || namedIntrinsicOperator};
 
 // R609 defined-operator ->
 //        defined-unary-op | defined-binary-op | extended-intrinsic-op
@@ -723,8 +722,9 @@ TYPE_PARSER(construct<EntityDecl>(objectName, maybe(arraySpec),
 TYPE_PARSER(lookAhead(name / "( )") >> construct<NullInit>(expr))
 
 // R807 access-spec -> PUBLIC | PRIVATE
-TYPE_PARSER(construct<AccessSpec>("PUBLIC" >> pure(AccessSpec::Kind::Public)) ||
-    construct<AccessSpec>("PRIVATE" >> pure(AccessSpec::Kind::Private)))
+TYPE_PARSER(
+    construct<AccessSpec>("PUBLIC" >> pure(common::AccessSpecKind::Public)) ||
+    construct<AccessSpec>("PRIVATE" >> pure(common::AccessSpecKind::Private)))
 
 // R808 language-binding-spec ->
 //        BIND ( C [, NAME = scalar-default-char-constant-expr] )
@@ -801,9 +801,10 @@ TYPE_PARSER(construct<ImpliedShapeSpec>(nonemptyList(assumedImpliedSpec)))
 TYPE_PARSER(construct<AssumedRankSpec>(".."_tok))
 
 // R826 intent-spec -> IN | OUT | INOUT
-TYPE_PARSER(construct<IntentSpec>("IN OUT" >> pure(IntentSpec::Intent::InOut) ||
-    "IN" >> pure(IntentSpec::Intent::In) ||
-    "OUT" >> pure(IntentSpec::Intent::Out)))
+TYPE_PARSER(
+    construct<IntentSpec>("IN OUT" >> pure(common::IntentSpecKind::InOut) ||
+        "IN" >> pure(common::IntentSpecKind::In) ||
+        "OUT" >> pure(common::IntentSpecKind::Out)))
 
 // R827 access-stmt -> access-spec [[::] access-id-list]
 TYPE_PARSER(construct<AccessStmt>(accessSpec,
@@ -836,8 +837,9 @@ TYPE_PARSER(construct<BindStmt>(languageBindingSpec / maybe("::"_tok),
     nonemptyList("expected bind entities"_err_en_US, Parser<BindEntity>{})))
 
 // R833 bind-entity -> entity-name | / common-block-name /
-TYPE_PARSER(construct<BindEntity>(pure(BindEntity::Kind::Object), name) ||
-    construct<BindEntity>("/" >> pure(BindEntity::Kind::Common), name / "/"))
+TYPE_PARSER(construct<BindEntity>(pure(common::BindEntityKind::Object), name) ||
+    construct<BindEntity>(
+        "/" >> pure(common::BindEntityKind::Common), name / "/"))
 
 // R834 codimension-stmt -> CODIMENSION [::] codimension-decl-list
 TYPE_PARSER(construct<CodimensionStmt>("CODIMENSION" >> maybe("::"_tok) >>
@@ -973,8 +975,10 @@ TYPE_PARSER(construct<SaveStmt>(
 
 // R857 saved-entity -> object-name | proc-pointer-name | / common-block-name /
 // R858 proc-pointer-name -> name
-TYPE_PARSER(construct<SavedEntity>(pure(SavedEntity::Kind::Entity), name) ||
-    construct<SavedEntity>("/" >> pure(SavedEntity::Kind::Common), name / "/"))
+TYPE_PARSER(
+    construct<SavedEntity>(pure(common::SavedEntityKind::Entity), name) ||
+    construct<SavedEntity>(
+        "/" >> pure(common::SavedEntityKind::Common), name / "/"))
 
 // R859 target-stmt -> TARGET [::] target-decl-list
 TYPE_PARSER(construct<TargetStmt>("TARGET" >> maybe("::"_tok) >>
@@ -989,8 +993,8 @@ TYPE_PARSER(construct<VolatileStmt>("VOLATILE" >> maybe("::"_tok) >>
 
 // R866 implicit-name-spec -> EXTERNAL | TYPE
 constexpr auto implicitNameSpec{
-    "EXTERNAL" >> pure(ImplicitStmt::ImplicitNoneNameSpec::External) ||
-    "TYPE" >> pure(ImplicitStmt::ImplicitNoneNameSpec::Type)};
+    "EXTERNAL" >> pure(common::ImplicitNoneNameSpec::External) ||
+    "TYPE" >> pure(common::ImplicitNoneNameSpec::Type)};
 
 // R863 implicit-stmt ->
 //        IMPLICIT implicit-spec-list |
diff --git a/flang/lib/Parser/executable-parsers.cpp b/flang/lib/Parser/executable-parsers.cpp
index a61bf2ce1551e9e..0972a1463007de4 100644
--- a/flang/lib/Parser/executable-parsers.cpp
+++ b/flang/lib/Parser/executable-parsers.cpp
@@ -440,8 +440,8 @@ TYPE_CONTEXT_PARSER("computed GOTO statement"_en_US,
 // R1161 error-stop-stmt ->
 //         ERROR STOP [stop-code] [, QUIET = scalar-logical-expr]
 TYPE_CONTEXT_PARSER("STOP statement"_en_US,
-    construct<StopStmt>("STOP" >> pure(StopStmt::Kind::Stop) ||
-            "ERROR STOP"_sptok >> pure(StopStmt::Kind::ErrorStop),
+    construct<StopStmt>("STOP" >> pure(common::StopKind::Stop) ||
+            "ERROR STOP"_sptok >> pure(common::StopKind::ErrorStop),
         maybe(Parser<StopCode>{}), maybe(", QUIET =" >> scalarLogicalExpr)))
 
 // R1162 stop-code -> scalar-default-char-expr | scalar-int-expr
diff --git a/flang/lib/Parser/io-parsers.cpp b/flang/lib/Parser/io-parsers.cpp
index ca0dbedc8da427d..a187e9cfa97cb48 100644
--- a/flang/lib/Parser/io-parsers.cpp
+++ b/flang/lib/Parser/io-parsers.cpp
@@ -61,25 +61,25 @@ constexpr auto errLabel{construct<ErrLabel>(label)};
 
 TYPE_PARSER(first(construct<ConnectSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "ACCESS =" >> pure(ConnectSpec::CharExpr::Kind::Access),
+        "ACCESS =" >> pure(common::ConnectCharExprKind::Access),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "ACTION =" >> pure(ConnectSpec::CharExpr::Kind::Action),
+        "ACTION =" >> pure(common::ConnectCharExprKind::Action),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "ASYNCHRONOUS =" >> pure(ConnectSpec::CharExpr::Kind::Asynchronous),
+        "ASYNCHRONOUS =" >> pure(common::ConnectCharExprKind::Asynchronous),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "BLANK =" >> pure(ConnectSpec::CharExpr::Kind::Blank),
+        "BLANK =" >> pure(common::ConnectCharExprKind::Blank),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "DECIMAL =" >> pure(ConnectSpec::CharExpr::Kind::Decimal),
+        "DECIMAL =" >> pure(common::ConnectCharExprKind::Decimal),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "DELIM =" >> pure(ConnectSpec::CharExpr::Kind::Delim),
+        "DELIM =" >> pure(common::ConnectCharExprKind::Delim),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "ENCODING =" >> pure(ConnectSpec::CharExpr::Kind::Encoding),
+        "ENCODING =" >> pure(common::ConnectCharExprKind::Encoding),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>("ERR =" >> errLabel),
     construct<ConnectSpec>("FILE =" >> fileNameExpr),
@@ -87,42 +87,42 @@ TYPE_PARSER(first(construct<ConnectSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
         "nonstandard usage: NAME= in place of FILE="_port_en_US,
         construct<ConnectSpec>("NAME =" >> fileNameExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "FORM =" >> pure(ConnectSpec::CharExpr::Kind::Form),
+        "FORM =" >> pure(common::ConnectCharExprKind::Form),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>("IOMSG =" >> msgVariable),
     construct<ConnectSpec>("IOSTAT =" >> statVariable),
     construct<ConnectSpec>(construct<ConnectSpec::Newunit>(
         "NEWUNIT =" >> scalar(integer(variable)))),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "PAD =" >> pure(ConnectSpec::CharExpr::Kind::Pad),
+        "PAD =" >> pure(common::ConnectCharExprKind::Pad),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "POSITION =" >> pure(ConnectSpec::CharExpr::Kind::Position),
+        "POSITION =" >> pure(common::ConnectCharExprKind::Position),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(
         construct<ConnectSpec::Recl>("RECL =" >> scalarIntExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "ROUND =" >> pure(ConnectSpec::CharExpr::Kind::Round),
+        "ROUND =" >> pure(common::ConnectCharExprKind::Round),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-        "SIGN =" >> pure(ConnectSpec::CharExpr::Kind::Sign),
+        "SIGN =" >> pure(common::ConnectCharExprKind::Sign),
         scalarDefaultCharExpr)),
     construct<ConnectSpec>("STATUS =" >> statusExpr),
     extension<LanguageFeature::Carriagecontrol>(
         "nonstandard usage: CARRIAGECONTROL="_port_en_US,
         construct<ConnectSpec>(
             construct<ConnectSpec::CharExpr>("CARRIAGECONTROL =" >>
-                    pure(ConnectSpec::CharExpr::Kind::Carriagecontrol),
+                    pure(common::ConnectCharExprKind::Carriagecontrol),
                 scalarDefaultCharExpr))),
     extension<LanguageFeature::Convert>(
         "nonstandard usage: CONVERT="_port_en_US,
         construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-            "CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert),
+            "CONVERT =" >> pure(common::ConnectCharExprKind::Convert),
             scalarDefaultCharExpr))),
     extension<LanguageFeature::Dispose>(
         "nonstandard usage: DISPOSE="_port_en_US,
         construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
-            "DISPOSE =" >> pure(ConnectSpec::CharExpr::Kind::Dispose),
+            "DISPOSE =" >> pure(common::ConnectCharExprKind::Dispose),
             scalarDefaultCharExpr)))))
 
 // R1209 close-spec ->
@@ -192,20 +192,20 @@ TYPE_PARSER(first(construct<IoControlSpec>("UNIT =" >> ioUnit),
     construct<IoControlSpec>("NML =" >> name),
     construct<IoControlSpec>(
         "ADVANCE =" >> construct<IoControlSpec::CharExpr>(
-                           pure(IoControlSpec::CharExpr::Kind::Advance),
+                           pure(common::IoControlCharExprKind::Advance),
                            scalarDefaultCharExpr)),
     construct<IoControlSpec>(construct<IoControlSpec::Asynchronous>(
         "ASYNCHRONOUS =" >> scalarDefaultCharConstantExpr)),
     construct<IoControlSpec>("BLANK =" >>
         construct<IoControlSpec::CharExpr>(
-            pure(IoControlSpec::CharExpr::Kind::Blank), scalarDefaultCharExpr)),
+            pure(common::IoControlCharExprKind::Blank), scalarDefaultCharExpr)),
     construct<IoControlSpec>(
         "DECIMAL =" >> construct<IoControlSpec::CharExpr>(
-                           pure(IoControlSpec::CharExpr::Kind::Decimal),
+                           pure(common::IoControlCharExprKind::Decimal),
                            scalarDefaultCharExpr)),
     construct<IoControlSpec>("DELIM =" >>
         construct<IoControlSpec::CharExpr>(
-            pure(IoControlSpec::CharExpr::Kind::Delim), scalarDefaultCharExpr)),
+            pure(common::IoControlCharExprKind::Delim), scalarDefaultCharExpr)),
     construct<IoControlSpec>("END =" >> endLabel),
     construct<IoControlSpec>("EOR =" >> eorLabel),
     construct<IoControlSpec>("ERR =" >> errLabel),
@@ -214,17 +214,17 @@ TYPE_PARSER(first(construct<IoControlSpec>("UNIT =" >> ioUnit),
     construct<IoControlSpec>("IOSTAT = " >> statVariable),
     construct<IoControlSpec>("PAD =" >>
         construct<IoControlSpec::CharExpr>(
-            pure(IoControlSpec::CharExpr::Kind::Pad), scalarDefaultCharExpr)),
+            pure(common::IoControlCharExprKind::Pad), scalarDefaultCharExpr)),
     construct<IoControlSpec>(
         "POS =" >> construct<IoControlSpec::Pos>(scalarIntExpr)),
     construct<IoControlSpec>(
         "REC =" >> construct<IoControlSpec::Rec>(scalarIntExpr)),
     construct<IoControlSpec>("ROUND =" >>
         construct<IoControlSpec::CharExpr>(
-            pure(IoControlSpec::CharExpr::Kind::Round), scalarDefaultCharExpr)),
+            pure(common::IoControlCharExprKind::Round), scalarDefaultCharExpr)),
     construct<IoControlSpec>("SIGN =" >>
         construct<IoControlSpec::CharExpr>(
-            pure(IoControlSpec::CharExpr::Kind::Sign), scalarDefaultCharExpr)),
+            pure(common::IoControlCharExprKind::Sign), scalarDefaultCharExpr)),
     construct<IoControlSpec>(
         "SIZE =" >> construct<IoControlSpec::Size>(scalarIntVariable))))
 
@@ -374,135 +374,135 @@ TYPE_PARSER(first(construct<InquireSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
     construct<InquireSpec>("FILE =" >> fileNameExpr),
     construct<InquireSpec>(
         "ACCESS =" >> construct<InquireSpec::CharVar>(
-                          pure(InquireSpec::CharVar::Kind::Access),
+                          pure(common::InquireCharVarKind::Access),
                           scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "ACTION =" >> construct<InquireSpec::CharVar>(
-                          pure(InquireSpec::CharVar::Kind::Action),
+                          pure(common::InquireCharVarKind::Action),
                           scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "ASYNCHRONOUS =" >> construct<InquireSpec::CharVar>(
-                                pure(InquireSpec::CharVar::Kind::Asynchronous),
+                                pure(common::InquireCharVarKind::Asynchronous),
                                 scalarDefaultCharVariable)),
     construct<InquireSpec>("BLANK =" >>
-        construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Blank),
+        construct<InquireSpec::CharVar>(pure(common::InquireCharVarKind::Blank),
             scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "DECIMAL =" >> construct<InquireSpec::CharVar>(
-                           pure(InquireSpec::CharVar::Kind::Decimal),
+                           pure(common::InquireCharVarKind::Decimal),
                            scalarDefaultCharVariable)),
     construct<InquireSpec>("DELIM =" >>
-        construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Delim),
+        construct<InquireSpec::CharVar>(pure(common::InquireCharVarKind::Delim),
             scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "DIRECT =" >> construct<InquireSpec::CharVar>(
-                          pure(InquireSpec::CharVar::Kind::Direct),
+                          pure(common::InquireCharVarKind::Direct),
                           scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "ENCODING =" >> construct<InquireSpec::CharVar>(
-                            pure(InquireSpec::CharVar::Kind::Encoding),
+                            pure(common::InquireCharVarKind::Encoding),
                             scalarDefaultCharVariable)),
     construct<InquireSpec>("ERR =" >> errLabel),
     construct<InquireSpec>("EXIST =" >>
         construct<InquireSpec::LogVar>(
-            pure(InquireSpec::LogVar::Kind::Exist), scalarLogicalVariable)),
+            pure(common::InquireLogVarKind::Exist), scalarLogicalVariable)),
     construct<InquireSpec>("FORM =" >>
         construct<InquireSpec::CharVar>(
-            pure(InquireSpec::CharVar::Kind::Form), scalarDefaultCharVariable)),
+            pure(common::InquireCharVarKind::Form), scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "FORMATTED =" >> construct<InquireSpec::CharVar>(
-                             pure(InquireSpec::CharVar::Kind::Formatted),
+                             pure(common::InquireCharVarKind::Formatted),
                              scalarDefaultCharVariable)),
     construct<InquireSpec>("ID =" >> idExpr),
     construct<InquireSpec>("IOMSG =" >>
-        construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Iomsg),
+        construct<InquireSpec::CharVar>(pure(common::InquireCharVarKind::Iomsg),
             scalarDefaultCharVariable)),
     construct<InquireSpec>("IOSTAT =" >>
-        construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Iostat),
+        construct<InquireSpec::IntVar>(pure(common::InquireIntVarKind::Iostat),
             scalar(integer(variable)))),
     construct<InquireSpec>("NAME =" >>
         construct<InquireSpec::CharVar>(
-            pure(InquireSpec::CharVar::Kind::Name), scalarDefaultCharVariable)),
+            pure(common::InquireCharVarKind::Name), scalarDefaultCharVariable)),
     construct<InquireSpec>("NAMED =" >>
         construct<InquireSpec::LogVar>(
-            pure(InquireSpec::LogVar::Kind::Named), scalarLogicalVariable)),
+            pure(common::InquireLogVarKind::Named), scalarLogicalVariable)),
     construct<InquireSpec>("NEXTREC =" >>
-        construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Nextrec),
+        construct<InquireSpec::IntVar>(pure(common::InquireIntVarKind::Nextrec),
             scalar(integer(variable)))),
     construct<InquireSpec>("NUMBER =" >>
-        construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Number),
+        construct<InquireSpec::IntVar>(pure(common::InquireIntVarKind::Number),
             scalar(integer(variable)))),
     construct<InquireSpec>("OPENED =" >>
         construct<InquireSpec::LogVar>(
-            pure(InquireSpec::LogVar::Kind::Opened), scalarLogicalVariable)),
+            pure(common::InquireLogVarKind::Opened), scalarLogicalVariable)),
     construct<InquireSpec>("PAD =" >>
         construct<InquireSpec::CharVar>(
-            pure(InquireSpec::CharVar::Kind::Pad), scalarDefaultCharVariable)),
+            pure(common::InquireCharVarKind::Pad), scalarDefaultCharVariable)),
     construct<InquireSpec>("PENDING =" >>
         construct<InquireSpec::LogVar>(
-            pure(InquireSpec::LogVar::Kind::Pending), scalarLogicalVariable)),
+            pure(common::InquireLogVarKind::Pending), scalarLogicalVariable)),
     construct<InquireSpec>("POS =" >>
         construct<InquireSpec::IntVar>(
-            pure(InquireSpec::IntVar::Kind::Pos), scalar(integer(variable)))),
+            pure(common::InquireIntVarKind::Pos), scalar(integer(variable)))),
     construct<InquireSpec>(
         "POSITION =" >> construct<InquireSpec::CharVar>(
-                            pure(InquireSpec::CharVar::Kind::Position),
+                            pure(common::InquireCharVarKind::Position),
                             scalarDefaultCharVariable)),
     construct<InquireSpec>("READ =" >>
         construct<InquireSpec::CharVar>(
-            pure(InquireSpec::CharVar::Kind::Read), scalarDefaultCharVariable)),
+            pure(common::InquireCharVarKind::Read), scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "READWRITE =" >> construct<InquireSpec::CharVar>(
-                             pure(InquireSpec::CharVar::Kind::Readwrite),
+                             pure(common::InquireCharVarKind::Readwrite),
                              scalarDefaultCharVariable)),
     construct<InquireSpec>("RECL =" >>
         construct<InquireSpec::IntVar>(
-            pure(InquireSpec::IntVar::Kind::Recl), scalar(integer(variable)))),
+            pure(common::InquireIntVarKind::Recl), scalar(integer(variable)))),
     construct<InquireSpec>("ROUND =" >>
-        construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Round),
+        construct<InquireSpec::CharVar>(pure(common::InquireCharVarKind::Round),
             scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "SEQUENTIAL =" >> construct<InquireSpec::CharVar>(
-                              pure(InquireSpec::CharVar::Kind::Sequential),
+                              pure(common::InquireCharVarKind::Sequential),
                               scalarDefaultCharVariable)),
     construct<InquireSpec>("SIGN =" >>
         construct<InquireSpec::CharVar>(
-            pure(InquireSpec::CharVar::Kind::Sign), scalarDefaultCharVariable)),
+            pure(common::InquireCharVarKind::Sign), scalarDefaultCharVariable)),
     construct<InquireSpec>("SIZE =" >>
         construct<InquireSpec::IntVar>(
-            pure(InquireSpec::IntVar::Kind::Size), scalar(integer(variable)))),
+            pure(common::InquireIntVarKind::Size), scalar(integer(variable)))),
     construct<InquireSpec>(
         "STREAM =" >> construct<InquireSpec::CharVar>(
-                          pure(InquireSpec::CharVar::Kind::Stream),
+                          pure(common::InquireCharVarKind::Stream),
                           scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "STATUS =" >> construct<InquireSpec::CharVar>(
-                          pure(InquireSpec::CharVar::Kind::Status),
+                          pure(common::InquireCharVarKind::Status),
                           scalarDefaultCharVariable)),
     construct<InquireSpec>(
         "UNFORMATTED =" >> construct<InquireSpec::CharVar>(
-                               pure(InquireSpec::CharVar::Kind::Unformatted),
+                               pure(common::InquireCharVarKind::Unformatted),
                                scalarDefaultCharVariable)),
     construct<InquireSpec>("WRITE =" >>
-        construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Write),
+        construct<InquireSpec::CharVar>(pure(common::InquireCharVarKind::Write),
             scalarDefaultCharVariable)),
     extension<LanguageFeature::Carriagecontrol>(
         "nonstandard usage: CARRIAGECONTROL="_port_en_US,
         construct<InquireSpec>("CARRIAGECONTROL =" >>
             construct<InquireSpec::CharVar>(
-                pure(InquireSpec::CharVar::Kind::Carriagecontrol),
+                pure(common::InquireCharVarKind::Carriagecontrol),
                 scalarDefaultCharVariable))),
     extension<LanguageFeature::Convert>(
         "nonstandard usage: CONVERT="_port_en_US,
         construct<InquireSpec>(
             "CONVERT =" >> construct<InquireSpec::CharVar>(
-                               pure(InquireSpec::CharVar::Kind::Convert),
+                               pure(common::InquireCharVarKind::Convert),
                                scalarDefaultCharVariable))),
     extension<LanguageFeature::Dispose>(
         "nonstandard usage: DISPOSE="_port_en_US,
         construct<InquireSpec>(
             "DISPOSE =" >> construct<InquireSpec::CharVar>(
-                               pure(InquireSpec::CharVar::Kind::Dispose),
+                               pure(common::InquireCharVarKind::Dispose),
                                scalarDefaultCharVariable)))))
 
 // R1230 inquire-stmt ->
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index afa12b88019bd9a..f4d20bcc688d3ff 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -88,17 +88,17 @@ TYPE_PARSER(construct<AccCollapseArg>(
 // 2.5.15 Reduction
 // Operator for reduction
 TYPE_PARSER(sourced(construct<AccReductionOperator>(
-    first("+" >> pure(AccReductionOperator::Operator::Plus),
-        "*" >> pure(AccReductionOperator::Operator::Multiply),
-        "MAX" >> pure(AccReductionOperator::Operator::Max),
-        "MIN" >> pure(AccReductionOperator::Operator::Min),
-        "IAND" >> pure(AccReductionOperator::Operator::Iand),
-        "IOR" >> pure(AccReductionOperator::Operator::Ior),
-        "IEOR" >> pure(AccReductionOperator::Operator::Ieor),
-        ".AND." >> pure(AccReductionOperator::Operator::And),
-        ".OR." >> pure(AccReductionOperator::Operator::Or),
-        ".EQV." >> pure(AccReductionOperator::Operator::Eqv),
-        ".NEQV." >> pure(AccReductionOperator::Operator::Neqv)))))
+    first("+" >> pure(common::AccReductionOperatorKind::Plus),
+        "*" >> pure(common::AccReductionOperatorKind::Multiply),
+        "MAX" >> pure(common::AccReductionOperatorKind::Max),
+        "MIN" >> pure(common::AccReductionOperatorKind::Min),
+        "IAND" >> pure(common::AccReductionOperatorKind::Iand),
+        "IOR" >> pure(common::AccReductionOperatorKind::Ior),
+        "IEOR" >> pure(common::AccReductionOperatorKind::Ieor),
+        ".AND." >> pure(common::AccReductionOperatorKind::And),
+        ".OR." >> pure(common::AccReductionOperatorKind::Or),
+        ".EQV." >> pure(common::AccReductionOperatorKind::Eqv),
+        ".NEQV." >> pure(common::AccReductionOperatorKind::Neqv)))))
 
 // 2.15.1 Bind clause
 TYPE_PARSER(sourced(construct<AccBindClause>(name)) ||
@@ -117,8 +117,8 @@ TYPE_PARSER(construct<AccSelfClause>(Parser<AccObjectList>{}) ||
 
 // Modifier for copyin, copyout, cache and create
 TYPE_PARSER(construct<AccDataModifier>(
-    first("ZERO:" >> pure(AccDataModifier::Modifier::Zero),
-        "READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly))))
+    first("ZERO:" >> pure(common::AccDataModifierKind::Zero),
+        "READONLY:" >> pure(common::AccDataModifierKind::ReadOnly))))
 
 // Combined directives
 TYPE_PARSER(sourced(construct<AccCombinedDirective>(
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index b30a3a1eb2a151f..850f530c529d93c 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -26,27 +26,27 @@ constexpr auto endOmpLine = space >> endOfLine;
 // OpenMP Clauses
 // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
 TYPE_PARSER(construct<OmpDefaultClause>(
-    "PRIVATE" >> pure(OmpDefaultClause::Type::Private) ||
-    "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) ||
-    "SHARED" >> pure(OmpDefaultClause::Type::Shared) ||
-    "NONE" >> pure(OmpDefaultClause::Type::None)))
+    "PRIVATE" >> pure(common::OmpDefaultClauseKind::Private) ||
+    "FIRSTPRIVATE" >> pure(common::OmpDefaultClauseKind::Firstprivate) ||
+    "SHARED" >> pure(common::OmpDefaultClauseKind::Shared) ||
+    "NONE" >> pure(common::OmpDefaultClauseKind::None)))
 
 // 2.5 PROC_BIND (MASTER | CLOSE | SPREAD)
 TYPE_PARSER(construct<OmpProcBindClause>(
-    "CLOSE" >> pure(OmpProcBindClause::Type::Close) ||
-    "MASTER" >> pure(OmpProcBindClause::Type::Master) ||
-    "SPREAD" >> pure(OmpProcBindClause::Type::Spread)))
+    "CLOSE" >> pure(common::OmpProcBindClauseKind::Close) ||
+    "MASTER" >> pure(common::OmpProcBindClauseKind::Master) ||
+    "SPREAD" >> pure(common::OmpProcBindClauseKind::Spread)))
 
 // 2.15.5.1 MAP ([ [ALWAYS[,]] map-type : ] variable-name-list)
 //          map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE
 TYPE_PARSER(construct<OmpMapType>(
     maybe("ALWAYS" >> construct<OmpMapType::Always>() / maybe(","_tok)),
-    ("TO"_id >> pure(OmpMapType::Type::To) ||
-        "FROM" >> pure(OmpMapType::Type::From) ||
-        "TOFROM" >> pure(OmpMapType::Type::Tofrom) ||
-        "ALLOC" >> pure(OmpMapType::Type::Alloc) ||
-        "RELEASE" >> pure(OmpMapType::Type::Release) ||
-        "DELETE" >> pure(OmpMapType::Type::Delete)) /
+    ("TO"_id >> pure(common::OmpMapKind::To) ||
+        "FROM" >> pure(common::OmpMapKind::From) ||
+        "TOFROM" >> pure(common::OmpMapKind::Tofrom) ||
+        "ALLOC" >> pure(common::OmpMapKind::Alloc) ||
+        "RELEASE" >> pure(common::OmpMapKind::Release) ||
+        "DELETE" >> pure(common::OmpMapKind::Delete)) /
         ":"))
 
 TYPE_PARSER(construct<OmpMapClause>(
@@ -58,76 +58,84 @@ TYPE_PARSER(construct<OmpMapClause>(
 //  DEFAULT
 //  variable-category -> SCALAR | AGGREGATE | ALLOCATABLE | POINTER
 TYPE_PARSER(construct<OmpDefaultmapClause>(
-    construct<OmpDefaultmapClause::ImplicitBehavior>(
-        "ALLOC" >> pure(OmpDefaultmapClause::ImplicitBehavior::Alloc) ||
-        "TO"_id >> pure(OmpDefaultmapClause::ImplicitBehavior::To) ||
-        "FROM" >> pure(OmpDefaultmapClause::ImplicitBehavior::From) ||
-        "TOFROM" >> pure(OmpDefaultmapClause::ImplicitBehavior::Tofrom) ||
+    construct<common::OmpDefaultmapClauseImplicitBehavior>(
+        "ALLOC" >> pure(common::OmpDefaultmapClauseImplicitBehavior::Alloc) ||
+        "TO"_id >> pure(common::OmpDefaultmapClauseImplicitBehavior::To) ||
+        "FROM" >> pure(common::OmpDefaultmapClauseImplicitBehavior::From) ||
+        "TOFROM" >> pure(common::OmpDefaultmapClauseImplicitBehavior::Tofrom) ||
         "FIRSTPRIVATE" >>
-            pure(OmpDefaultmapClause::ImplicitBehavior::Firstprivate) ||
-        "NONE" >> pure(OmpDefaultmapClause::ImplicitBehavior::None) ||
-        "DEFAULT" >> pure(OmpDefaultmapClause::ImplicitBehavior::Default)),
+            pure(common::OmpDefaultmapClauseImplicitBehavior::Firstprivate) ||
+        "NONE" >> pure(common::OmpDefaultmapClauseImplicitBehavior::None) ||
+        "DEFAULT" >>
+            pure(common::OmpDefaultmapClauseImplicitBehavior::Default)),
     maybe(":" >>
-        construct<OmpDefaultmapClause::VariableCategory>(
-            "SCALAR" >> pure(OmpDefaultmapClause::VariableCategory::Scalar) ||
+        construct<common::OmpDefaultmapClauseVariableCategory>("SCALAR" >>
+                pure(common::OmpDefaultmapClauseVariableCategory::Scalar) ||
             "AGGREGATE" >>
-                pure(OmpDefaultmapClause::VariableCategory::Aggregate) ||
+                pure(common::OmpDefaultmapClauseVariableCategory::Aggregate) ||
             "ALLOCATABLE" >>
-                pure(OmpDefaultmapClause::VariableCategory::Allocatable) ||
+                pure(
+                    common::OmpDefaultmapClauseVariableCategory::Allocatable) ||
             "POINTER" >>
-                pure(OmpDefaultmapClause::VariableCategory::Pointer)))))
+                pure(common::OmpDefaultmapClauseVariableCategory::Pointer)))))
 
 // 2.7.1 SCHEDULE ([modifier1 [, modifier2]:]kind[, chunk_size])
 //       Modifier ->  MONITONIC | NONMONOTONIC | SIMD
 //       kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME
 //       chunk_size -> ScalarIntExpr
 TYPE_PARSER(construct<OmpScheduleModifierType>(
-    "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) ||
-    "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) ||
-    "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd)))
+    "MONOTONIC" >> pure(common::OmpScheduleModifierKind::Monotonic) ||
+    "NONMONOTONIC" >> pure(common::OmpScheduleModifierKind::Nonmonotonic) ||
+    "SIMD" >> pure(common::OmpScheduleModifierKind::Simd)))
 
 TYPE_PARSER(construct<OmpScheduleModifier>(Parser<OmpScheduleModifierType>{},
     maybe("," >> Parser<OmpScheduleModifierType>{}) / ":"))
 
 TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}),
-    "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) ||
-        "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) ||
-        "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) ||
-        "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) ||
-        "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
+    "STATIC" >> pure(common::OmpScheduleClauseKind::Static) ||
+        "DYNAMIC" >> pure(common::OmpScheduleClauseKind::Dynamic) ||
+        "GUIDED" >> pure(common::OmpScheduleClauseKind::Guided) ||
+        "AUTO" >> pure(common::OmpScheduleClauseKind::Auto) ||
+        "RUNTIME" >> pure(common::OmpScheduleClauseKind::Runtime),
     maybe("," >> scalarIntExpr)))
 
 // device([ device-modifier :] scalar-integer-expression)
 TYPE_PARSER(construct<OmpDeviceClause>(
     maybe(
-        ("ANCESTOR" >> pure(OmpDeviceClause::DeviceModifier::Ancestor) ||
-            "DEVICE_NUM" >> pure(OmpDeviceClause::DeviceModifier::Device_Num)) /
+        ("ANCESTOR" >> pure(common::OmpDeviceClauseDeviceModifier::Ancestor) ||
+            "DEVICE_NUM" >>
+                pure(common::OmpDeviceClauseDeviceModifier::Device_Num)) /
         ":"),
     scalarIntExpr))
 
 // device_type(any | host | nohost)
 TYPE_PARSER(construct<OmpDeviceTypeClause>(
-    "ANY" >> pure(OmpDeviceTypeClause::Type::Any) ||
-    "HOST" >> pure(OmpDeviceTypeClause::Type::Host) ||
-    "NOHOST" >> pure(OmpDeviceTypeClause::Type::Nohost)))
+    "ANY" >> pure(common::OmpDeviceTypeClauseKind::Any) ||
+    "HOST" >> pure(common::OmpDeviceTypeClauseKind::Host) ||
+    "NOHOST" >> pure(common::OmpDeviceTypeClauseKind::Nohost)))
 
 // 2.12 IF (directive-name-modifier: scalar-logical-expr)
 TYPE_PARSER(construct<OmpIfClause>(
     maybe(
-        ("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
-            "SIMD" >> pure(OmpIfClause::DirectiveNameModifier::Simd) ||
+        ("PARALLEL" >>
+                pure(common::OmpIfClauseDirectiveNameModifier::Parallel) ||
+            "SIMD" >> pure(common::OmpIfClauseDirectiveNameModifier::Simd) ||
             "TARGET ENTER DATA" >>
-                pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
+                pure(common::OmpIfClauseDirectiveNameModifier::
+                        TargetEnterData) ||
             "TARGET EXIT DATA" >>
-                pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
+                pure(
+                    common::OmpIfClauseDirectiveNameModifier::TargetExitData) ||
             "TARGET DATA" >>
-                pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
+                pure(common::OmpIfClauseDirectiveNameModifier::TargetData) ||
             "TARGET UPDATE" >>
-                pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
-            "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
-            "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) ||
-            "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
-            "TEAMS" >> pure(OmpIfClause::DirectiveNameModifier::Teams)) /
+                pure(common::OmpIfClauseDirectiveNameModifier::TargetUpdate) ||
+            "TARGET" >>
+                pure(common::OmpIfClauseDirectiveNameModifier::Target) ||
+            "TASK"_id >> pure(common::OmpIfClauseDirectiveNameModifier::Task) ||
+            "TASKLOOP" >>
+                pure(common::OmpIfClauseDirectiveNameModifier::Taskloop) ||
+            "TEAMS" >> pure(common::OmpIfClauseDirectiveNameModifier::Teams)) /
         ":"),
     scalarLogicalExpr))
 
@@ -180,10 +188,10 @@ TYPE_PARSER(construct<OmpDependSinkVecLength>(
 TYPE_PARSER(
     construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
 
-TYPE_PARSER(
-    construct<OmpDependenceType>("IN"_id >> pure(OmpDependenceType::Type::In) ||
-        "INOUT" >> pure(OmpDependenceType::Type::Inout) ||
-        "OUT" >> pure(OmpDependenceType::Type::Out)))
+TYPE_PARSER(construct<OmpDependenceType>(
+    "IN"_id >> pure(common::OmpDependenceKind::In) ||
+    "INOUT" >> pure(common::OmpDependenceKind::Inout) ||
+    "OUT" >> pure(common::OmpDependenceKind::Out)))
 
 TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
     construct<OmpDependClause>(construct<OmpDependClause::Sink>(
@@ -196,10 +204,10 @@ TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
 // 2.15.3.7 LINEAR (linear-list: linear-step)
 //          linear-list -> list | modifier(list)
 //          linear-modifier -> REF | VAL | UVAL
-TYPE_PARSER(
-    construct<OmpLinearModifier>("REF" >> pure(OmpLinearModifier::Type::Ref) ||
-        "VAL" >> pure(OmpLinearModifier::Type::Val) ||
-        "UVAL" >> pure(OmpLinearModifier::Type::Uval)))
+TYPE_PARSER(construct<OmpLinearModifier>(
+    "REF" >> pure(common::OmpLinearModifierKind::Ref) ||
+    "VAL" >> pure(common::OmpLinearModifierKind::Val) ||
+    "UVAL" >> pure(common::OmpLinearModifierKind::Uval)))
 
 TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
     construct<OmpLinearClause>(
@@ -214,14 +222,13 @@ TYPE_PARSER(construct<OmpAlignedClause>(
     Parser<OmpObjectList>{}, maybe(":" >> scalarIntConstantExpr)))
 
 // 2.9.5 ORDER ([order-modifier :]concurrent)
-TYPE_PARSER(construct<OmpOrderModifier>(
-    "REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) ||
+TYPE_PARSER(construct<OmpOrderModifier>("REPRODUCIBLE" >>
+                pure(common::OmpOrderModifierKind::Reproducible)) ||
     construct<OmpOrderModifier>(
-    "UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained)))
+        "UNCONSTRAINED" >> pure(common::OmpOrderModifierKind::Unconstrained)))
 
-TYPE_PARSER(construct<OmpOrderClause>(
-    maybe(Parser<OmpOrderModifier>{} / ":"),
-    "CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent)))
+TYPE_PARSER(construct<OmpOrderClause>(maybe(Parser<OmpOrderModifier>{} / ":"),
+    "CONCURRENT" >> pure(common::OmpOrderClauseKind::Concurrent)))
 
 TYPE_PARSER(
     construct<OmpObject>(designator) || construct<OmpObject>("/" >> name / "/"))
@@ -399,10 +406,10 @@ TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
 
 // 2.14.1 construct-type-clause -> PARALLEL | SECTIONS | DO | TASKGROUP
 TYPE_PARSER(sourced(construct<OmpCancelType>(
-    first("PARALLEL" >> pure(OmpCancelType::Type::Parallel),
-        "SECTIONS" >> pure(OmpCancelType::Type::Sections),
-        "DO" >> pure(OmpCancelType::Type::Do),
-        "TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup)))))
+    first("PARALLEL" >> pure(common::OmpCancelKind::Parallel),
+        "SECTIONS" >> pure(common::OmpCancelKind::Sections),
+        "DO" >> pure(common::OmpCancelKind::Do),
+        "TASKGROUP" >> pure(common::OmpCancelKind::Taskgroup)))))
 
 // 2.14.2 Cancellation Point construct
 TYPE_PARSER(sourced(construct<OpenMPCancellationPointConstruct>(
@@ -432,9 +439,9 @@ TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
 //                               acq_rel
 //                               relaxed
 TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
-    "SEQ_CST" >> pure(OmpAtomicDefaultMemOrderClause::Type::SeqCst) ||
-    "ACQ_REL" >> pure(OmpAtomicDefaultMemOrderClause::Type::AcqRel) ||
-    "RELAXED" >> pure(OmpAtomicDefaultMemOrderClause::Type::Relaxed)))
+    "SEQ_CST" >> pure(common::OmpAtomicDefaultMemOrderClauseKind::SeqCst) ||
+    "ACQ_REL" >> pure(common::OmpAtomicDefaultMemOrderClauseKind::AcqRel) ||
+    "RELAXED" >> pure(common::OmpAtomicDefaultMemOrderClauseKind::Relaxed)))
 
 // 2.17.7 Atomic construct
 //        atomic-clause -> memory-order-clause | HINT(hint-expression)
diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index 521ae43097adc6a..418dd6bc9ded775 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -246,8 +246,8 @@ TYPE_PARSER(construct<ModuleSubprogram>(indirect(functionSubprogram)) ||
 
 // R1410 module-nature -> INTRINSIC | NON_INTRINSIC
 constexpr auto moduleNature{
-    "INTRINSIC" >> pure(UseStmt::ModuleNature::Intrinsic) ||
-    "NON_INTRINSIC" >> pure(UseStmt::ModuleNature::Non_Intrinsic)};
+    "INTRINSIC" >> pure(common::ModuleNature::Intrinsic) ||
+    "NON_INTRINSIC" >> pure(common::ModuleNature::Non_Intrinsic)};
 
 // R1409 use-stmt ->
 //         USE [[, module-nature] ::] module-name [, rename-list] |
@@ -351,10 +351,10 @@ constexpr auto specificProcedures{
 
 // R1506 procedure-stmt -> [MODULE] PROCEDURE [::] specific-procedure-list
 TYPE_PARSER(construct<ProcedureStmt>("MODULE PROCEDURE"_sptok >>
-                    pure(ProcedureStmt::Kind::ModuleProcedure),
+                    pure(common::ProcedureKind::ModuleProcedure),
                 maybe("::"_tok) >> specificProcedures) ||
     construct<ProcedureStmt>(
-        "PROCEDURE" >> pure(ProcedureStmt::Kind::Procedure),
+        "PROCEDURE" >> pure(common::ProcedureKind::Procedure),
         maybe("::"_tok) >> specificProcedures))
 
 // R1508 generic-spec ->
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index d7626c0ea762937..158c1d2df7a2e98 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -94,46 +94,46 @@ class UnparseVisitor {
   void Unparse(const Name &x) { // R603
     Put(x.ToString());
   }
-  void Unparse(const DefinedOperator::IntrinsicOperator &x) { // R608
+  void Unparse(const common::IntrinsicOperator &x) { // R608
     switch (x) {
-    case DefinedOperator::IntrinsicOperator::Power:
+    case common::IntrinsicOperator::Power:
       Put("**");
       break;
-    case DefinedOperator::IntrinsicOperator::Multiply:
+    case common::IntrinsicOperator::Multiply:
       Put('*');
       break;
-    case DefinedOperator::IntrinsicOperator::Divide:
+    case common::IntrinsicOperator::Divide:
       Put('/');
       break;
-    case DefinedOperator::IntrinsicOperator::Add:
+    case common::IntrinsicOperator::Add:
       Put('+');
       break;
-    case DefinedOperator::IntrinsicOperator::Subtract:
+    case common::IntrinsicOperator::Subtract:
       Put('-');
       break;
-    case DefinedOperator::IntrinsicOperator::Concat:
+    case common::IntrinsicOperator::Concat:
       Put("//");
       break;
-    case DefinedOperator::IntrinsicOperator::LT:
+    case common::IntrinsicOperator::LT:
       Put('<');
       break;
-    case DefinedOperator::IntrinsicOperator::LE:
+    case common::IntrinsicOperator::LE:
       Put("<=");
       break;
-    case DefinedOperator::IntrinsicOperator::EQ:
+    case common::IntrinsicOperator::EQ:
       Put("==");
       break;
-    case DefinedOperator::IntrinsicOperator::NE:
+    case common::IntrinsicOperator::NE:
       Put("/=");
       break;
-    case DefinedOperator::IntrinsicOperator::GE:
+    case common::IntrinsicOperator::GE:
       Put(">=");
       break;
-    case DefinedOperator::IntrinsicOperator::GT:
+    case common::IntrinsicOperator::GT:
       Put('>');
       break;
     default:
-      Put('.'), Word(DefinedOperator::EnumToString(x)), Put('.');
+      Put('.'), Word(common::EnumToString(x)), Put('.');
     }
   }
   void Post(const Star &) { Put('*'); } // R701 &c.
@@ -614,7 +614,8 @@ class UnparseVisitor {
     Walk(x.t, " :: ");
   }
   void Unparse(const BindEntity &x) { // R833
-    bool isCommon{std::get<BindEntity::Kind>(x.t) == BindEntity::Kind::Common};
+    bool isCommon{std::get<common::BindEntityKind>(x.t) ==
+        common::BindEntityKind::Common};
     const char *slash{isCommon ? "/" : ""};
     Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
   }
@@ -677,8 +678,8 @@ class UnparseVisitor {
     Word("SAVE"), Walk(" :: ", x.v, ", ");
   }
   void Unparse(const SavedEntity &x) { // R857, R858
-    bool isCommon{
-        std::get<SavedEntity::Kind>(x.t) == SavedEntity::Kind::Common};
+    bool isCommon{std::get<common::SavedEntityKind>(x.t) ==
+        common::SavedEntityKind::Common};
     const char *slash{isCommon ? "/" : ""};
     Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
   }
@@ -693,13 +694,12 @@ class UnparseVisitor {
   }
   void Unparse(const ImplicitStmt &x) { // R863
     Word("IMPLICIT ");
-    common::visit(
-        common::visitors{
-            [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
-            [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
-              Word("NONE"), Walk(" (", y, ", ", ")");
-            },
-        },
+    common::visit(common::visitors{
+                      [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
+                      [&](const std::list<common::ImplicitNoneNameSpec> &y) {
+                        Word("NONE"), Walk(" (", y, ", ", ")");
+                      },
+                  },
         x.u);
   }
   void Unparse(const ImplicitSpec &x) { // R864
@@ -1140,7 +1140,7 @@ class UnparseVisitor {
     Word("CONTINUE");
   }
   void Unparse(const StopStmt &x) { // R1160, R1161
-    if (std::get<StopStmt::Kind>(x.t) == StopStmt::Kind::ErrorStop) {
+    if (std::get<common::StopKind>(x.t) == common::StopKind::ErrorStop) {
       Word("ERROR ");
     }
     Word("STOP"), Walk(" ", std::get<std::optional<StopCode>>(x.t));
@@ -1632,8 +1632,8 @@ class UnparseVisitor {
     Outdent(), Word("END INTERFACE"), Walk(" ", x.v);
   }
   void Unparse(const ProcedureStmt &x) { // R1506
-    if (std::get<ProcedureStmt::Kind>(x.t) ==
-        ProcedureStmt::Kind::ModuleProcedure) {
+    if (std::get<common::ProcedureKind>(x.t) ==
+        common::ProcedureKind::ModuleProcedure) {
       Word("MODULE ");
     }
     Word("PROCEDURE :: ");
@@ -2045,11 +2045,12 @@ class UnparseVisitor {
   }
   void Unparse(const OmpScheduleClause &x) {
     Walk(std::get<std::optional<OmpScheduleModifier>>(x.t), ":");
-    Walk(std::get<OmpScheduleClause::ScheduleType>(x.t));
+    Walk(std::get<common::OmpScheduleClauseKind>(x.t));
     Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
   }
   void Unparse(const OmpDeviceClause &x) {
-    Walk(std::get<std::optional<OmpDeviceClause::DeviceModifier>>(x.t), ":");
+    Walk(std::get<std::optional<common::OmpDeviceClauseDeviceModifier>>(x.t),
+        ":");
     Walk(std::get<ScalarIntExpr>(x.t));
   }
   void Unparse(const OmpAlignedClause &x) {
@@ -2058,7 +2059,8 @@ class UnparseVisitor {
     Walk(std::get<std::optional<ScalarIntConstantExpr>>(x.t));
   }
   void Unparse(const OmpIfClause &x) {
-    Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t), ":");
+    Walk(std::get<std::optional<common::OmpIfClauseDirectiveNameModifier>>(x.t),
+        ":");
     Walk(std::get<ScalarLogicalExpr>(x.t));
   }
   void Unparse(const OmpLinearClause::WithoutModifier &x) {
@@ -2111,7 +2113,7 @@ class UnparseVisitor {
   }
   void Unparse(const OmpOrderClause &x) {
     Walk(std::get<std::optional<OmpOrderModifier>>(x.t), ":");
-    Walk(std::get<OmpOrderClause::Type>(x.t));
+    Walk(std::get<common::OmpOrderClauseKind>(x.t));
   }
   void Unparse(const OmpDependSinkVecLength &x) {
     Walk(std::get<DefinedOperator>(x.t));
@@ -2146,9 +2148,10 @@ class UnparseVisitor {
         x.u);
   }
   void Unparse(const OmpDefaultmapClause &x) {
-    Walk(std::get<OmpDefaultmapClause::ImplicitBehavior>(x.t));
+    Walk(std::get<common::OmpDefaultmapClauseImplicitBehavior>(x.t));
     Walk(":",
-        std::get<std::optional<OmpDefaultmapClause::VariableCategory>>(x.t));
+        std::get<std::optional<common::OmpDefaultmapClauseVariableCategory>>(
+            x.t));
   }
 #define GEN_FLANG_CLAUSE_UNPARSE
 #include "llvm/Frontend/OpenMP/OMP.inc"
@@ -2308,13 +2311,13 @@ class UnparseVisitor {
 
   void Unparse(const OmpAtomicDefaultMemOrderClause &x) {
     switch (x.v) {
-    case OmpAtomicDefaultMemOrderClause::Type::SeqCst:
+    case common::OmpAtomicDefaultMemOrderClauseKind::SeqCst:
       Word("SEQ_CST");
       break;
-    case OmpAtomicDefaultMemOrderClause::Type::AcqRel:
+    case common::OmpAtomicDefaultMemOrderClauseKind::AcqRel:
       Word("ACQ_REL");
       break;
-    case OmpAtomicDefaultMemOrderClause::Type::Relaxed:
+    case common::OmpAtomicDefaultMemOrderClauseKind::Relaxed:
       Word("RELAXED");
       break;
     }
@@ -2689,38 +2692,38 @@ class UnparseVisitor {
   }
   void Unparse(const PauseStmt &x) { Word("PAUSE"), Walk(" ", x.v); }
 
-#define WALK_NESTED_ENUM(CLASS, ENUM) \
-  void Unparse(const CLASS::ENUM &x) { Word(CLASS::EnumToString(x)); }
-  WALK_NESTED_ENUM(AccDataModifier, Modifier)
-  WALK_NESTED_ENUM(AccessSpec, Kind) // R807
-  WALK_NESTED_ENUM(AccReductionOperator, Operator)
-  WALK_NESTED_ENUM(common, TypeParamAttr) // R734
-  WALK_NESTED_ENUM(common, CUDADataAttr) // CUDA
-  WALK_NESTED_ENUM(common, CUDASubprogramAttrs) // CUDA
-  WALK_NESTED_ENUM(IntentSpec, Intent) // R826
-  WALK_NESTED_ENUM(ImplicitStmt, ImplicitNoneNameSpec) // R866
-  WALK_NESTED_ENUM(ConnectSpec::CharExpr, Kind) // R1205
-  WALK_NESTED_ENUM(IoControlSpec::CharExpr, Kind)
-  WALK_NESTED_ENUM(InquireSpec::CharVar, Kind)
-  WALK_NESTED_ENUM(InquireSpec::IntVar, Kind)
-  WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
-  WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
-  WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
-  WALK_NESTED_ENUM(OmpProcBindClause, Type) // OMP PROC_BIND
-  WALK_NESTED_ENUM(OmpDefaultClause, Type) // OMP DEFAULT
-  WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP DEFAULTMAP
-  WALK_NESTED_ENUM(OmpDefaultmapClause, VariableCategory) // OMP DEFAULTMAP
-  WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
-  WALK_NESTED_ENUM(OmpLinearModifier, Type) // OMP linear-modifier
-  WALK_NESTED_ENUM(OmpDependenceType, Type) // OMP dependence-type
-  WALK_NESTED_ENUM(OmpMapType, Type) // OMP map-type
-  WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
-  WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier
-  WALK_NESTED_ENUM(OmpDeviceTypeClause, Type) // OMP DEVICE_TYPE
-  WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
-  WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
-  WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP order-type
-  WALK_NESTED_ENUM(OmpOrderModifier, Kind) // OMP order-modifier
+#define WALK_NESTED_ENUM(ENUM) \
+  void Unparse(const common::ENUM &x) { Word(common::EnumToString(x)); }
+  WALK_NESTED_ENUM(AccDataModifierKind)
+  WALK_NESTED_ENUM(AccessSpecKind) // R807
+  WALK_NESTED_ENUM(AccReductionOperatorKind)
+  WALK_NESTED_ENUM(TypeParamAttr) // R734
+  WALK_NESTED_ENUM(CUDADataAttr) // CUDA
+  WALK_NESTED_ENUM(CUDASubprogramAttrs) // CUDA
+  WALK_NESTED_ENUM(IntentSpecKind) // R826
+  WALK_NESTED_ENUM(ImplicitNoneNameSpec) // R866
+  WALK_NESTED_ENUM(ConnectCharExprKind) // R1205
+  WALK_NESTED_ENUM(IoControlCharExprKind)
+  WALK_NESTED_ENUM(InquireCharVarKind)
+  WALK_NESTED_ENUM(InquireIntVarKind)
+  WALK_NESTED_ENUM(InquireLogVarKind)
+  WALK_NESTED_ENUM(ProcedureKind) // R1506
+  WALK_NESTED_ENUM(ModuleNature) // R1410
+  WALK_NESTED_ENUM(OmpProcBindClauseKind) // OMP PROC_BIND
+  WALK_NESTED_ENUM(OmpDefaultClauseKind) // OMP DEFAULT
+  WALK_NESTED_ENUM(OmpDefaultmapClauseImplicitBehavior) // OMP DEFAULTMAP
+  WALK_NESTED_ENUM(OmpDefaultmapClauseVariableCategory) // OMP DEFAULTMAP
+  WALK_NESTED_ENUM(OmpScheduleModifierKind) // OMP schedule-modifier
+  WALK_NESTED_ENUM(OmpLinearModifierKind) // OMP linear-modifier
+  WALK_NESTED_ENUM(OmpDependenceKind) // OMP dependence-type
+  WALK_NESTED_ENUM(OmpMapKind) // OMP map-type
+  WALK_NESTED_ENUM(OmpScheduleClauseKind) // OMP schedule-type
+  WALK_NESTED_ENUM(OmpDeviceClauseDeviceModifier) // OMP device modifier
+  WALK_NESTED_ENUM(OmpDeviceTypeClauseKind) // OMP DEVICE_TYPE
+  WALK_NESTED_ENUM(OmpIfClauseDirectiveNameModifier) // OMP directive-modifier
+  WALK_NESTED_ENUM(OmpCancelKind) // OMP cancel-type
+  WALK_NESTED_ENUM(OmpOrderClauseKind) // OMP order-type
+  WALK_NESTED_ENUM(OmpOrderModifierKind) // OMP order-modifier
 #undef WALK_NESTED_ENUM
 
   void Unparse(const CUFKernelDoConstruct::Directive &x) {
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 692a7a408947aa7..da6a4269586b0fb 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -22,33 +22,33 @@
   }
 
 using ReductionOpsSet =
-    Fortran::common::EnumSet<Fortran::parser::AccReductionOperator::Operator,
-        Fortran::parser::AccReductionOperator::Operator_enumSize>;
+    Fortran::common::EnumSet<Fortran::common::AccReductionOperatorKind,
+        Fortran::common::AccReductionOperatorKind_enumSize>;
 
 static ReductionOpsSet reductionIntegerSet{
-    Fortran::parser::AccReductionOperator::Operator::Plus,
-    Fortran::parser::AccReductionOperator::Operator::Multiply,
-    Fortran::parser::AccReductionOperator::Operator::Max,
-    Fortran::parser::AccReductionOperator::Operator::Min,
-    Fortran::parser::AccReductionOperator::Operator::Iand,
-    Fortran::parser::AccReductionOperator::Operator::Ior,
-    Fortran::parser::AccReductionOperator::Operator::Ieor};
+    Fortran::common::AccReductionOperatorKind::Plus,
+    Fortran::common::AccReductionOperatorKind::Multiply,
+    Fortran::common::AccReductionOperatorKind::Max,
+    Fortran::common::AccReductionOperatorKind::Min,
+    Fortran::common::AccReductionOperatorKind::Iand,
+    Fortran::common::AccReductionOperatorKind::Ior,
+    Fortran::common::AccReductionOperatorKind::Ieor};
 
 static ReductionOpsSet reductionRealSet{
-    Fortran::parser::AccReductionOperator::Operator::Plus,
-    Fortran::parser::AccReductionOperator::Operator::Multiply,
-    Fortran::parser::AccReductionOperator::Operator::Max,
-    Fortran::parser::AccReductionOperator::Operator::Min};
+    Fortran::common::AccReductionOperatorKind::Plus,
+    Fortran::common::AccReductionOperatorKind::Multiply,
+    Fortran::common::AccReductionOperatorKind::Max,
+    Fortran::common::AccReductionOperatorKind::Min};
 
 static ReductionOpsSet reductionComplexSet{
-    Fortran::parser::AccReductionOperator::Operator::Plus,
-    Fortran::parser::AccReductionOperator::Operator::Multiply};
+    Fortran::common::AccReductionOperatorKind::Plus,
+    Fortran::common::AccReductionOperatorKind::Multiply};
 
 static ReductionOpsSet reductionLogicalSet{
-    Fortran::parser::AccReductionOperator::Operator::And,
-    Fortran::parser::AccReductionOperator::Operator::Or,
-    Fortran::parser::AccReductionOperator::Operator::Eqv,
-    Fortran::parser::AccReductionOperator::Operator::Neqv};
+    Fortran::common::AccReductionOperatorKind::And,
+    Fortran::common::AccReductionOperatorKind::Or,
+    Fortran::common::AccReductionOperatorKind::Eqv,
+    Fortran::common::AccReductionOperatorKind::Neqv};
 
 namespace Fortran::semantics {
 
@@ -411,7 +411,7 @@ void AccStructureChecker::Enter(const parser::AccClause::Create &c) {
   const auto &modifierClause{c.v};
   if (const auto &modifier{
           std::get<std::optional<parser::AccDataModifier>>(modifierClause.t)}) {
-    if (modifier->v != parser::AccDataModifier::Modifier::Zero) {
+    if (modifier->v != common::AccDataModifierKind::Zero) {
       context_.Say(GetContext().clauseSource,
           "Only the ZERO modifier is allowed for the %s clause "
           "on the %s directive"_err_en_US,
@@ -442,7 +442,7 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyin &c) {
     if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyin)) {
       return;
     }
-    if (modifier->v != parser::AccDataModifier::Modifier::ReadOnly) {
+    if (modifier->v != common::AccDataModifierKind::ReadOnly) {
       context_.Say(GetContext().clauseSource,
           "Only the READONLY modifier is allowed for the %s clause "
           "on the %s directive"_err_en_US,
@@ -464,7 +464,7 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) {
     if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyout)) {
       return;
     }
-    if (modifier->v != parser::AccDataModifier::Modifier::Zero) {
+    if (modifier->v != common::AccDataModifierKind::Zero) {
       context_.Say(GetContext().clauseSource,
           "Only the ZERO modifier is allowed for the %s clause "
           "on the %s directive"_err_en_US,
diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp
index a1ed4660efde79c..79728915d33604c 100644
--- a/flang/lib/Semantics/check-do-forall.cpp
+++ b/flang/lib/Semantics/check-do-forall.cpp
@@ -305,8 +305,8 @@ class DoConcurrentBodyEnforce {
   void Post(const parser::IoControlSpec &ioControlSpec) {
     if (auto *charExpr{
             std::get_if<parser::IoControlSpec::CharExpr>(&ioControlSpec.u)}) {
-      if (std::get<parser::IoControlSpec::CharExpr::Kind>(charExpr->t) ==
-          parser::IoControlSpec::CharExpr::Kind::Advance) {
+      if (std::get<common::IoControlCharExprKind>(charExpr->t) ==
+          common::IoControlCharExprKind::Advance) {
         SayWithDo(context_, currentStatementSourcePosition_,
             "ADVANCE specifier is not allowed in DO"
             " CONCURRENT"_err_en_US,
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 314dee5a232226c..56c2444b33acd44 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -109,7 +109,7 @@ static std::string Normalize(const std::string &value) {
 
 void IoChecker::Enter(const parser::ConnectSpec::CharExpr &spec) {
   IoSpecKind specKind{};
-  using ParseKind = parser::ConnectSpec::CharExpr::Kind;
+  using ParseKind = common::ConnectCharExprKind;
   switch (std::get<ParseKind>(spec.t)) {
   case ParseKind::Access:
     specKind = IoSpecKind::Access;
@@ -343,7 +343,7 @@ void IoChecker::Enter(const parser::InquireSpec &spec) {
 
 void IoChecker::Enter(const parser::InquireSpec::CharVar &spec) {
   IoSpecKind specKind{};
-  using ParseKind = parser::InquireSpec::CharVar::Kind;
+  using ParseKind = common::InquireCharVarKind;
   switch (std::get<ParseKind>(spec.t)) {
   case ParseKind::Access:
     specKind = IoSpecKind::Access;
@@ -435,8 +435,8 @@ void IoChecker::Enter(const parser::InquireSpec::CharVar &spec) {
 
 void IoChecker::Enter(const parser::InquireSpec::IntVar &spec) {
   IoSpecKind specKind{};
-  using ParseKind = parser::InquireSpec::IntVar::Kind;
-  switch (std::get<parser::InquireSpec::IntVar::Kind>(spec.t)) {
+  using ParseKind = common::InquireIntVarKind;
+  switch (std::get<ParseKind>(spec.t)) {
   case ParseKind::Iostat:
     specKind = IoSpecKind::Iostat;
     break;
@@ -463,8 +463,8 @@ void IoChecker::Enter(const parser::InquireSpec::IntVar &spec) {
 
 void IoChecker::Enter(const parser::InquireSpec::LogVar &spec) {
   IoSpecKind specKind{};
-  using ParseKind = parser::InquireSpec::LogVar::Kind;
-  switch (std::get<parser::InquireSpec::LogVar::Kind>(spec.t)) {
+  using ParseKind = common::InquireLogVarKind;
+  switch (std::get<ParseKind>(spec.t)) {
   case ParseKind::Exist:
     specKind = IoSpecKind::Exist;
     break;
@@ -502,7 +502,7 @@ void IoChecker::Enter(const parser::IoControlSpec::Asynchronous &spec) {
 
 void IoChecker::Enter(const parser::IoControlSpec::CharExpr &spec) {
   IoSpecKind specKind{};
-  using ParseKind = parser::IoControlSpec::CharExpr::Kind;
+  using ParseKind = common::IoControlCharExprKind;
   switch (std::get<ParseKind>(spec.t)) {
   case ParseKind::Advance:
     specKind = IoSpecKind::Advance;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index ffd577aa203756d..89842acdd1b7362 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1232,7 +1232,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
               [&](const parser::OmpClause::DeviceType &deviceTypeClause) {
                 deviceTypeClauseFound = true;
                 if (deviceTypeClause.v.v !=
-                    parser::OmpDeviceTypeClause::Type::Host) {
+                    common::OmpDeviceTypeClauseKind::Host) {
                   // Function / subroutine explicitly marked as runnable by the
                   // target device.
                   deviceConstructFound_ = true;
@@ -1502,7 +1502,7 @@ void OmpStructureChecker::Leave(
 }
 
 void OmpStructureChecker::CheckCancellationNest(
-    const parser::CharBlock &source, const parser::OmpCancelType::Type &type) {
+    const parser::CharBlock &source, const common::OmpCancelKind &type) {
   if (CurrentDirectiveIsNested()) {
     // If construct-type-clause is taskgroup, the cancellation construct must be
     // closely nested inside a task or a taskloop construct and the cancellation
@@ -1514,7 +1514,7 @@ void OmpStructureChecker::CheckCancellationNest(
     // cancellation construct.
     bool eligibleCancellation{false};
     switch (type) {
-    case parser::OmpCancelType::Type::Taskgroup:
+    case common::OmpCancelKind::Taskgroup:
       if (llvm::omp::nestedCancelTaskgroupAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
@@ -1543,24 +1543,23 @@ void OmpStructureChecker::CheckCancellationNest(
             "With %s clause, %s construct must be closely nested inside TASK "
             "or TASKLOOP construct and %s region must be closely nested inside "
             "TASKGROUP region"_err_en_US,
-            parser::ToUpperCaseLetters(
-                parser::OmpCancelType::EnumToString(type)),
+            parser::ToUpperCaseLetters(common::EnumToString(type)),
             ContextDirectiveAsFortran(), ContextDirectiveAsFortran());
       }
       return;
-    case parser::OmpCancelType::Type::Sections:
+    case common::OmpCancelKind::Sections:
       if (llvm::omp::nestedCancelSectionsAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
       }
       break;
-    case Fortran::parser::OmpCancelType::Type::Do:
+    case common::OmpCancelKind::Do:
       if (llvm::omp::nestedCancelDoAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
       }
       break;
-    case parser::OmpCancelType::Type::Parallel:
+    case common::OmpCancelKind::Parallel:
       if (llvm::omp::nestedCancelParallelAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
@@ -1571,7 +1570,7 @@ void OmpStructureChecker::CheckCancellationNest(
       context_.Say(source,
           "With %s clause, %s construct cannot be closely nested inside %s "
           "construct"_err_en_US,
-          parser::ToUpperCaseLetters(parser::OmpCancelType::EnumToString(type)),
+          parser::ToUpperCaseLetters(common::EnumToString(type)),
           ContextDirectiveAsFortran(),
           parser::ToUpperCaseLetters(
               getDirectiveName(GetContextParent().directive).str()));
@@ -1579,37 +1578,33 @@ void OmpStructureChecker::CheckCancellationNest(
   } else {
     // The cancellation directive cannot be orphaned.
     switch (type) {
-    case parser::OmpCancelType::Type::Taskgroup:
+    case common::OmpCancelKind::Taskgroup:
       context_.Say(source,
           "%s %s directive is not closely nested inside "
           "TASK or TASKLOOP"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(common::EnumToString(type)));
       break;
-    case parser::OmpCancelType::Type::Sections:
+    case common::OmpCancelKind::Sections:
       context_.Say(source,
           "%s %s directive is not closely nested inside "
           "SECTION or SECTIONS"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(common::EnumToString(type)));
       break;
-    case Fortran::parser::OmpCancelType::Type::Do:
+    case common::OmpCancelKind::Do:
       context_.Say(source,
           "%s %s directive is not closely nested inside "
           "the construct that matches the DO clause type"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(common::EnumToString(type)));
       break;
-    case parser::OmpCancelType::Type::Parallel:
+    case common::OmpCancelKind::Parallel:
       context_.Say(source,
           "%s %s directive is not closely nested inside "
           "the construct that matches the PARALLEL clause type"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(common::EnumToString(type)));
       break;
     }
   }
@@ -1953,15 +1948,15 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
     if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) {
       // only one schedule clause is allowed
       const auto &schedClause{std::get<parser::OmpClause::Schedule>(clause->u)};
-      if (ScheduleModifierHasType(schedClause.v,
-              parser::OmpScheduleModifierType::ModType::Nonmonotonic)) {
+      if (ScheduleModifierHasType(
+              schedClause.v, common::OmpScheduleModifierKind::Nonmonotonic)) {
         if (FindClause(llvm::omp::Clause::OMPC_ordered)) {
           context_.Say(clause->source,
               "The NONMONOTONIC modifier cannot be specified "
               "if an ORDERED clause is specified"_err_en_US);
         }
-        if (ScheduleModifierHasType(schedClause.v,
-                parser::OmpScheduleModifierType::ModType::Monotonic)) {
+        if (ScheduleModifierHasType(
+                schedClause.v, common::OmpScheduleModifierKind::Monotonic)) {
           context_.Say(clause->source,
               "The MONOTONIC and NONMONOTONIC modifiers "
               "cannot be both specified"_err_en_US);
@@ -2180,7 +2175,7 @@ bool OmpStructureChecker::CheckReductionOperators(
       common::visitors{
           [&](const parser::DefinedOperator &dOpr) {
             const auto &intrinsicOp{
-                std::get<parser::DefinedOperator::IntrinsicOperator>(dOpr.u)};
+                std::get<common::IntrinsicOperator>(dOpr.u)};
             ok = CheckIntrinsicOperator(intrinsicOp);
           },
           [&](const parser::ProcedureDesignator &procD) {
@@ -2204,17 +2199,17 @@ bool OmpStructureChecker::CheckReductionOperators(
   return ok;
 }
 bool OmpStructureChecker::CheckIntrinsicOperator(
-    const parser::DefinedOperator::IntrinsicOperator &op) {
+    const common::IntrinsicOperator &op) {
 
   switch (op) {
-  case parser::DefinedOperator::IntrinsicOperator::Add:
-  case parser::DefinedOperator::IntrinsicOperator::Multiply:
-  case parser::DefinedOperator::IntrinsicOperator::AND:
-  case parser::DefinedOperator::IntrinsicOperator::OR:
-  case parser::DefinedOperator::IntrinsicOperator::EQV:
-  case parser::DefinedOperator::IntrinsicOperator::NEQV:
+  case common::IntrinsicOperator::Add:
+  case common::IntrinsicOperator::Multiply:
+  case common::IntrinsicOperator::AND:
+  case common::IntrinsicOperator::OR:
+  case common::IntrinsicOperator::EQV:
+  case common::IntrinsicOperator::NEQV:
     return true;
-  case parser::DefinedOperator::IntrinsicOperator::Subtract:
+  case common::IntrinsicOperator::Subtract:
     context_.Say(GetContext().clauseSource,
         "The minus reduction operator is deprecated since OpenMP 5.2 and is "
         "not supported in the REDUCTION clause."_err_en_US,
@@ -2505,7 +2500,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
   CheckAllowed(llvm::omp::Clause::OMPC_defaultmap);
-  using VariableCategory = parser::OmpDefaultmapClause::VariableCategory;
+  using VariableCategory = common::OmpDefaultmapClauseVariableCategory;
   if (!std::get<std::optional<VariableCategory>>(x.v.t)) {
     context_.Say(GetContext().clauseSource,
         "The argument TOFROM:SCALAR must be specified on the DEFAULTMAP "
@@ -2514,7 +2509,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
   CheckAllowed(llvm::omp::Clause::OMPC_if);
-  using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier;
+  using dirNameModifier = common::OmpIfClauseDirectiveNameModifier;
   // TODO Check that, when multiple 'if' clauses are applied to a combined
   // construct, at most one of them applies to each directive.
   static std::unordered_map<dirNameModifier, OmpDirectiveSet>
@@ -2540,8 +2535,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
       context_
           .Say(GetContext().clauseSource,
               "Unmatched directive name modifier %s on the IF clause"_err_en_US,
-              parser::ToUpperCaseLetters(
-                  parser::OmpIfClause::EnumToString(*directiveName)))
+              parser::ToUpperCaseLetters(common::EnumToString(*directiveName)))
           .Attach(
               GetContext().directiveSource, "Cannot apply to directive"_en_US);
     }
@@ -2563,16 +2557,15 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
   }
 }
 
-void OmpStructureChecker::CheckAllowedMapTypes(
-    const parser::OmpMapType::Type &type,
-    const std::list<parser::OmpMapType::Type> &allowedMapTypeList) {
+void OmpStructureChecker::CheckAllowedMapTypes(const common::OmpMapKind &type,
+    const std::list<common::OmpMapKind> &allowedMapTypeList) {
   if (!llvm::is_contained(allowedMapTypeList, type)) {
     std::string commaSeperatedMapTypes;
     llvm::interleave(
         allowedMapTypeList.begin(), allowedMapTypeList.end(),
-        [&](const parser::OmpMapType::Type &mapType) {
-          commaSeperatedMapTypes.append(parser::ToUpperCaseLetters(
-              parser::OmpMapType::EnumToString(mapType)));
+        [&](const common::OmpMapKind &mapType) {
+          commaSeperatedMapTypes.append(
+              parser::ToUpperCaseLetters(common::EnumToString(mapType)));
         },
         [&] { commaSeperatedMapTypes.append(", "); });
     context_.Say(GetContext().clauseSource,
@@ -2586,7 +2579,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
   CheckAllowed(llvm::omp::Clause::OMPC_map);
 
   if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.v.t)}) {
-    using Type = parser::OmpMapType::Type;
+    using Type = common::OmpMapKind;
     const Type &type{std::get<Type>(maptype->t)};
     switch (GetContext().directive) {
     case llvm::omp::Directive::OMPD_target:
@@ -2613,7 +2606,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
 
 bool OmpStructureChecker::ScheduleModifierHasType(
     const parser::OmpScheduleClause &x,
-    const parser::OmpScheduleModifierType::ModType &type) {
+    const common::OmpScheduleModifierKind &type) {
   const auto &modifier{
       std::get<std::optional<parser::OmpScheduleModifier>>(x.t)};
   if (modifier) {
@@ -2637,13 +2630,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
     const auto &kind{std::get<1>(scheduleClause.t)};
     const auto &chunk{std::get<2>(scheduleClause.t)};
     if (chunk) {
-      if (kind == parser::OmpScheduleClause::ScheduleType::Runtime ||
-          kind == parser::OmpScheduleClause::ScheduleType::Auto) {
+      if (kind == common::OmpScheduleClauseKind::Runtime ||
+          kind == common::OmpScheduleClauseKind::Auto) {
         context_.Say(GetContext().clauseSource,
             "When SCHEDULE clause has %s specified, "
             "it must not have chunk size specified"_err_en_US,
-            parser::ToUpperCaseLetters(
-                parser::OmpScheduleClause::EnumToString(kind)));
+            parser::ToUpperCaseLetters(common::EnumToString(kind)));
       }
       if (const auto &chunkExpr{std::get<std::optional<parser::ScalarIntExpr>>(
               scheduleClause.t)}) {
@@ -2652,10 +2644,10 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
       }
     }
 
-    if (ScheduleModifierHasType(scheduleClause,
-            parser::OmpScheduleModifierType::ModType::Nonmonotonic)) {
-      if (kind != parser::OmpScheduleClause::ScheduleType::Dynamic &&
-          kind != parser::OmpScheduleClause::ScheduleType::Guided) {
+    if (ScheduleModifierHasType(
+            scheduleClause, common::OmpScheduleModifierKind::Nonmonotonic)) {
+      if (kind != common::OmpScheduleClauseKind::Dynamic &&
+          kind != common::OmpScheduleClauseKind::Guided) {
         context_.Say(GetContext().clauseSource,
             "The NONMONOTONIC modifier can only be specified with "
             "SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)"_err_en_US);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index cdff890ddd417f4..4f940a109f98be3 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -138,9 +138,9 @@ class OmpStructureChecker
   void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
   // specific clause related
   bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
-      const parser::OmpScheduleModifierType::ModType &);
-  void CheckAllowedMapTypes(const parser::OmpMapType::Type &,
-      const std::list<parser::OmpMapType::Type> &);
+      const common::OmpScheduleModifierKind &);
+  void CheckAllowedMapTypes(
+      const common::OmpMapKind &, const std::list<common::OmpMapKind> &);
   llvm::StringRef getClauseName(llvm::omp::Clause clause) override;
   llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override;
 
@@ -183,11 +183,10 @@ class OmpStructureChecker
   void CheckSIMDNest(const parser::OpenMPConstruct &x);
   void CheckTargetNest(const parser::OpenMPConstruct &x);
   void CheckCancellationNest(
-      const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
+      const parser::CharBlock &source, const common::OmpCancelKind &type);
   std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
   bool CheckReductionOperators(const parser::OmpClause::Reduction &);
-  bool CheckIntrinsicOperator(
-      const parser::DefinedOperator::IntrinsicOperator &);
+  bool CheckIntrinsicOperator(const common::IntrinsicOperator &);
   void CheckReductionTypeList(const parser::OmpClause::Reduction &);
   void CheckMasterNesting(const parser::OpenMPBlockConstruct &x);
   void ChecksOnOrderedAsBlock();
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 84f00ef82755ef9..c96f5be1f98c86e 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -170,8 +170,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
     const auto &objectList{std::get<parser::AccObjectList>(x.v.t)};
     const auto &modifier{
         std::get<std::optional<parser::AccDataModifier>>(x.v.t)};
-    if (modifier &&
-        (*modifier).v == parser::AccDataModifier::Modifier::ReadOnly) {
+    if (modifier && (*modifier).v == common::AccDataModifierKind::ReadOnly) {
       ResolveAccObjectList(objectList, Symbol::Flag::AccCopyInReadOnly);
     } else {
       ResolveAccObjectList(objectList, Symbol::Flag::AccCopyIn);
@@ -1686,16 +1685,16 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPAllocatorsConstruct &x) {
 void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) {
   if (!dirContext_.empty()) {
     switch (x.v) {
-    case parser::OmpDefaultClause::Type::Private:
+    case common::OmpDefaultClauseKind::Private:
       SetContextDefaultDSA(Symbol::Flag::OmpPrivate);
       break;
-    case parser::OmpDefaultClause::Type::Firstprivate:
+    case common::OmpDefaultClauseKind::Firstprivate:
       SetContextDefaultDSA(Symbol::Flag::OmpFirstPrivate);
       break;
-    case parser::OmpDefaultClause::Type::Shared:
+    case common::OmpDefaultClauseKind::Shared:
       SetContextDefaultDSA(Symbol::Flag::OmpShared);
       break;
-    case parser::OmpDefaultClause::Type::None:
+    case common::OmpDefaultClauseKind::None:
       SetContextDefaultDSA(Symbol::Flag::OmpNone);
       break;
     }
diff --git a/flang/lib/Semantics/resolve-labels.cpp b/flang/lib/Semantics/resolve-labels.cpp
index ac028019993cc62..380a7678efa4d01 100644
--- a/flang/lib/Semantics/resolve-labels.cpp
+++ b/flang/lib/Semantics/resolve-labels.cpp
@@ -424,11 +424,8 @@ class ParseTreeAnalyzer {
           const auto *op{std::get_if<parser::DefinedOperator>(&genericSpec->u)};
           if (endOp && op) {
             const auto *endIntrin{
-                std::get_if<parser::DefinedOperator::IntrinsicOperator>(
-                    &endOp->u)};
-            const auto *intrin{
-                std::get_if<parser::DefinedOperator::IntrinsicOperator>(
-                    &op->u)};
+                std::get_if<common::IntrinsicOperator>(&endOp->u)};
+            const auto *intrin{std::get_if<common::IntrinsicOperator>(&op->u)};
             ok = endIntrin && intrin && *endIntrin == *intrin;
           }
         }
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 2f8e5777c529020..25b1725c2b25a29 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -25,11 +25,11 @@
 
 namespace Fortran::semantics {
 
+using common::IntrinsicOperator;
 using common::LanguageFeature;
 using common::LogicalOperator;
 using common::NumericOperator;
 using common::RelationalOperator;
-using IntrinsicOperator = parser::DefinedOperator::IntrinsicOperator;
 
 static constexpr const char *operatorPrefix{"operator("};
 
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 0b4b940fa1d1c70..ab452fb64e75383 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -288,20 +288,20 @@ class AttrsVisitor : public virtual BaseVisitor {
 
   Attr AccessSpecToAttr(const parser::AccessSpec &x) {
     switch (x.v) {
-    case parser::AccessSpec::Kind::Public:
+    case common::AccessSpecKind::Public:
       return Attr::PUBLIC;
-    case parser::AccessSpec::Kind::Private:
+    case common::AccessSpecKind::Private:
       return Attr::PRIVATE;
     }
     llvm_unreachable("Switch covers all cases"); // suppress g++ warning
   }
   Attr IntentSpecToAttr(const parser::IntentSpec &x) {
     switch (x.v) {
-    case parser::IntentSpec::Intent::In:
+    case common::IntentSpecKind::In:
       return Attr::INTENT_IN;
-    case parser::IntentSpec::Intent::Out:
+    case common::IntentSpecKind::Out:
       return Attr::INTENT_OUT;
-    case parser::IntentSpec::Intent::InOut:
+    case common::IntentSpecKind::InOut:
       return Attr::INTENT_INOUT;
     }
     llvm_unreachable("Switch covers all cases"); // suppress g++ warning
@@ -382,7 +382,7 @@ class ImplicitRulesVisitor : public DeclTypeSpecVisitor {
 public:
   using DeclTypeSpecVisitor::Post;
   using DeclTypeSpecVisitor::Pre;
-  using ImplicitNoneNameSpec = parser::ImplicitStmt::ImplicitNoneNameSpec;
+  using ImplicitNoneNameSpec = common::ImplicitNoneNameSpec;
 
   void Post(const parser::ParameterStmt &);
   bool Pre(const parser::ImplicitStmt &);
@@ -812,7 +812,7 @@ class ModuleVisitor : public virtual ScopeHandler {
 
 class GenericHandler : public virtual ScopeHandler {
 protected:
-  using ProcedureKind = parser::ProcedureStmt::Kind;
+  using ProcedureKind = common::ProcedureKind;
   void ResolveSpecificsInGeneric(Symbol &, bool isEndOfSpecificationPart);
   void DeclaredPossibleSpecificProc(Symbol &);
 
@@ -2828,7 +2828,7 @@ bool ModuleVisitor::Pre(const parser::Rename::Operators &x) {
 bool ModuleVisitor::Pre(const parser::UseStmt &x) {
   std::optional<bool> isIntrinsic;
   if (x.nature) {
-    isIntrinsic = *x.nature == parser::UseStmt::ModuleNature::Intrinsic;
+    isIntrinsic = *x.nature == common::ModuleNature::Intrinsic;
   } else if (currScope().IsModule() && currScope().symbol() &&
       currScope().symbol()->attrs().test(Attr::INTRINSIC)) {
     // Intrinsic modules USE only other intrinsic modules
@@ -3284,7 +3284,7 @@ bool InterfaceVisitor::Pre(const parser::ProcedureStmt &x) {
   if (!isGeneric()) {
     Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US);
   } else {
-    auto kind{std::get<parser::ProcedureStmt::Kind>(x.t)};
+    auto kind{std::get<common::ProcedureKind>(x.t)};
     const auto &names{std::get<std::list<parser::Name>>(x.t)};
     AddSpecificProcs(names, kind);
   }
@@ -4449,10 +4449,10 @@ void DeclarationVisitor::Post(const parser::PointerDecl &x) {
 }
 
 bool DeclarationVisitor::Pre(const parser::BindEntity &x) {
-  auto kind{std::get<parser::BindEntity::Kind>(x.t)};
+  auto kind{std::get<common::BindEntityKind>(x.t)};
   auto &name{std::get<parser::Name>(x.t)};
   Symbol *symbol;
-  if (kind == parser::BindEntity::Kind::Object) {
+  if (kind == common::BindEntityKind::Object) {
     symbol = &HandleAttributeStmt(Attr::BIND_C, name);
   } else {
     symbol = &MakeCommonBlockSymbol(name);
@@ -5648,7 +5648,7 @@ bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
   const auto &bindingNames{std::get<std::list<parser::Name>>(x.t)};
   GenericSpecInfo info{genericSpec.value()};
   SourceName symbolName{info.symbolName()};
-  bool isPrivate{accessSpec ? accessSpec->v == parser::AccessSpec::Kind::Private
+  bool isPrivate{accessSpec ? accessSpec->v == common::AccessSpecKind::Private
                             : derivedTypeInfo_.privateBindings};
   auto *genericSymbol{FindInScope(symbolName)};
   if (genericSymbol) {
@@ -5980,9 +5980,9 @@ bool DeclarationVisitor::Pre(const parser::SaveStmt &x) {
     currScope().set_hasSAVE();
   } else {
     for (const parser::SavedEntity &y : x.v) {
-      auto kind{std::get<parser::SavedEntity::Kind>(y.t)};
+      auto kind{std::get<common::SavedEntityKind>(y.t)};
       const auto &name{std::get<parser::Name>(y.t)};
-      if (kind == parser::SavedEntity::Kind::Common) {
+      if (kind == common::SavedEntityKind::Common) {
         MakeCommonBlockSymbol(name);
         AddSaveName(specPartState_.saveInfo.commons, name.source);
       } else {
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 7c523971e8e2479..35c1125a2aad84e 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -954,8 +954,7 @@ class ImageControlStmtHelper {
   }
   bool operator()(const parser::StopStmt &stmt) {
     // STOP is an image control statement; ERROR STOP is not
-    return std::get<parser::StopStmt::Kind>(stmt.t) ==
-        parser::StopStmt::Kind::Stop;
+    return std::get<common::StopKind>(stmt.t) == common::StopKind::Stop;
   }
   bool operator()(const parser::IfStmt &stmt) {
     return (*this)(
diff --git a/flang/test/Parser/OpenMP/declare_target-device_type.f90 b/flang/test/Parser/OpenMP/declare_target-device_type.f90
index 2f6b68ab30f6e91..95baa8c3b5b42db 100644
--- a/flang/test/Parser/OpenMP/declare_target-device_type.f90
+++ b/flang/test/Parser/OpenMP/declare_target-device_type.f90
@@ -16,7 +16,7 @@ subroutine openmp_declare_target
     end do
 
 !PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct
-!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Host
-!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Nohost
-!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Any
+!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceTypeClauseKind = Host
+!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceTypeClauseKind = Nohost
+!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceTypeClauseKind = Any
 END subroutine openmp_declare_target
diff --git a/flang/test/Parser/OpenMP/order-clause01.f90 b/flang/test/Parser/OpenMP/order-clause01.f90
index d7efaf0f67c23b1..85ba8c05641a0dd 100644
--- a/flang/test/Parser/OpenMP/order-clause01.f90
+++ b/flang/test/Parser/OpenMP/order-clause01.f90
@@ -17,7 +17,7 @@ subroutine test_do_order()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_simd_order_reproducible()
  integer :: i, j = 1
@@ -33,8 +33,8 @@ subroutine test_simd_order_reproducible()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Reproducible
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Reproducible
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_do_simd_order_unconstrained()
  integer :: i, j = 1
@@ -50,8 +50,8 @@ subroutine test_do_simd_order_unconstrained()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Unconstrained
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Unconstrained
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_parallel_do_order()
  integer :: i, j = 1
@@ -67,7 +67,7 @@ subroutine test_parallel_do_order()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_parallel_do_simd_order_reproducible()
  integer :: i, j = 1
@@ -83,8 +83,8 @@ subroutine test_parallel_do_simd_order_reproducible()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Reproducible
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Reproducible
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_simd_order_unconstrained()
  integer :: i, j = 1
@@ -100,8 +100,8 @@ subroutine test_target_simd_order_unconstrained()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Unconstrained
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Unconstrained
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_parallel_do_order()
  integer :: i, j = 1
@@ -117,7 +117,7 @@ subroutine test_target_parallel_do_order()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_parallel_do_simd_order_reproducible()
  integer :: i, j = 1
@@ -133,8 +133,8 @@ subroutine test_target_parallel_do_simd_order_reproducible()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Reproducible
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Reproducible
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_teams_distribute_simd_order_unconstrained()
  integer :: i, j = 1
@@ -150,8 +150,8 @@ subroutine test_teams_distribute_simd_order_unconstrained()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Unconstrained
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Unconstrained
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_teams_distribute_parallel_do_order()
  integer :: i, j = 1
@@ -167,7 +167,7 @@ subroutine test_teams_distribute_parallel_do_order()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_teams_distribute_parallel_do_simd_order_reproducible()
  integer :: i, j = 1
@@ -183,8 +183,8 @@ subroutine test_teams_distribute_parallel_do_simd_order_reproducible()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Reproducible
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Reproducible
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_teams_distribute_simd_order_unconstrained()
  integer :: i, j = 1
@@ -200,8 +200,8 @@ subroutine test_target_teams_distribute_simd_order_unconstrained()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Unconstrained
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Unconstrained
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_teams_distribute_parallel_do_order()
  integer :: i, j = 1
@@ -217,7 +217,7 @@ subroutine test_target_teams_distribute_parallel_do_order()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_target_teams_distribute_parallel_do_simd_order_reproducible()
  integer :: i, j = 1
@@ -233,8 +233,8 @@ subroutine test_target_teams_distribute_parallel_do_simd_order_reproducible()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Reproducible
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Reproducible
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent
 
 subroutine test_taskloop_simd_order_unconstrained()
  integer :: i, j = 1
@@ -250,5 +250,5 @@ subroutine test_taskloop_simd_order_unconstrained()
 !PARSE-TREE-NEXT: OmpBeginLoopDirective
 !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
-!PARSE-TREE-NEXT: Kind = Unconstrained
-!PARSE-TREE-NEXT: Type = Concurrent
+!PARSE-TREE-NEXT: OmpOrderModifierKind = Unconstrained
+!PARSE-TREE-NEXT: OmpOrderClauseKind = Concurrent



More information about the flang-commits mailing list