[flang-commits] [flang] [flang] Enumeration Type: (PR 1/5) Foundation types + Parser (PR #192651)
via flang-commits
flang-commits at lists.llvm.org
Fri Apr 17 06:24:56 PDT 2026
https://github.com/kwyatt-ext created https://github.com/llvm/llvm-project/pull/192651
This PR creates the concept of an ENUMERATION TYPE from the Fortran 2023 Standard. It is implemented as a special case of a Derived Type internally to the compiler. It adds the parse/unparse support. The compiler will be able to recognize the syntax of an ENUMERATION TYPE and report to users that the feature is not yet implemented.
It is the 1st of 5 stacked PRs.
AI Usage Disclosure: AI tools (Claude Opus 4.6) were used to assist with implementation of this feature and test code generation. I have reviewed, modified, and tested all AI-generated code.
>From fd08cd19104776a016d95e10e2e10827ffef38ef Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Thu, 16 Apr 2026 12:47:22 -0500
Subject: [PATCH 1/2] Enumeration Type Sem-1: Foundation types + Parser (PRs
1-2)
Adds DerivedTypeSpec::Category::EnumerationType to the type system,
parse tree nodes for ENUMERATION TYPE per F2023, and parser/unparser
support. Includes a stub in resolve-names that rejects ENUMERATION TYPE
as 'not yet implemented' (enabled in Sem-2).
Files from original PRs 1-2.
---
flang/include/flang/Parser/dump-parse-tree.h | 4 +++
flang/include/flang/Parser/parse-tree.h | 38 +++++++++++++++++---
flang/include/flang/Semantics/symbol.h | 8 +++++
flang/include/flang/Semantics/tools.h | 2 ++
flang/include/flang/Semantics/type.h | 11 +++++-
flang/lib/Evaluate/type.cpp | 11 +++---
flang/lib/Lower/ConvertType.cpp | 3 ++
flang/lib/Parser/Fortran-parsers.cpp | 29 +++++++++++++++
flang/lib/Parser/program-parsers.cpp | 6 ++--
flang/lib/Parser/unparse.cpp | 16 +++++++++
flang/lib/Semantics/resolve-names.cpp | 7 ++++
flang/lib/Semantics/symbol.cpp | 1 +
flang/lib/Semantics/tools.cpp | 11 ++++++
flang/lib/Semantics/type.cpp | 20 +++++++++++
14 files changed, 155 insertions(+), 12 deletions(-)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index eefab487413da..1d37d03b60a6c 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -312,6 +312,7 @@ class ParseTreeDumper {
NODE(parser, EndChangeTeamStmt)
NODE(parser, EndCriticalStmt)
NODE(parser, EndDoStmt)
+ NODE(parser, EndEnumerationTypeStmt)
NODE(parser, EndEnumStmt)
NODE(parser, EndForallStmt)
NODE(parser, EndFunctionStmt)
@@ -333,6 +334,9 @@ class ParseTreeDumper {
NODE(parser, EnumDefStmt)
NODE(parser, Enumerator)
NODE(parser, EnumeratorDefStmt)
+ NODE(parser, EnumerationEnumeratorStmt)
+ NODE(parser, EnumerationTypeDef)
+ NODE(parser, EnumerationTypeStmt)
NODE(parser, EorLabel)
NODE(parser, EquivalenceObject)
NODE(parser, EquivalenceStmt)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 960ebbcc99efb..2dc5201278d20 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -156,6 +156,7 @@ struct SubroutineSubprogram; // R1534
// with order of the the requirement productions in the grammar.
struct DerivedTypeDef; // R726
struct EnumDef; // R759
+struct EnumerationTypeDef; // F2023 R766
struct TypeDeclarationStmt; // R801
struct AccessStmt; // R827
struct AllocatableStmt; // R829
@@ -392,13 +393,15 @@ struct OtherSpecificationStmt {
};
// R508 specification-construct ->
-// derived-type-def | enum-def | generic-stmt | interface-block |
-// parameter-stmt | procedure-declaration-stmt |
-// other-specification-stmt | type-declaration-stmt
+// derived-type-def | enum-def | enumeration-type-def |
+// generic-stmt | interface-block | parameter-stmt |
+// procedure-declaration-stmt | other-specification-stmt |
+// type-declaration-stmt
struct SpecificationConstruct {
UNION_CLASS_BOILERPLATE(SpecificationConstruct);
std::variant<common::Indirection<DerivedTypeDef>,
- common::Indirection<EnumDef>, Statement<common::Indirection<GenericStmt>>,
+ common::Indirection<EnumDef>, common::Indirection<EnumerationTypeDef>,
+ Statement<common::Indirection<GenericStmt>>,
common::Indirection<InterfaceBlock>,
Statement<common::Indirection<ParameterStmt>>,
Statement<common::Indirection<OldParameterStmt>>,
@@ -1230,6 +1233,33 @@ struct EnumDef {
t;
};
+// F2023 R767 enumeration-type-stmt ->
+// ENUMERATION TYPE [ [ , access-spec ] :: ] enumeration-type-name
+struct EnumerationTypeStmt {
+ TUPLE_CLASS_BOILERPLATE(EnumerationTypeStmt);
+ std::tuple<std::optional<AccessSpec>, Name> t;
+};
+
+// F2023 R768 enumeration-enumerator-stmt -> ENUMERATOR [ :: ]
+// enumerator-name-list
+WRAPPER_CLASS(EnumerationEnumeratorStmt, std::list<Name>);
+
+// F2023 R769 end-enumeration-type-stmt ->
+// END ENUMERATION TYPE [ enumeration-type-name ]
+WRAPPER_CLASS(EndEnumerationTypeStmt, std::optional<Name>);
+
+// F2023 R766 enumeration-type-def ->
+// enumeration-type-stmt
+// enumeration-enumerator-stmt [ enumeration-enumerator-stmt ]...
+// end-enumeration-type-stmt
+struct EnumerationTypeDef {
+ TUPLE_CLASS_BOILERPLATE(EnumerationTypeDef);
+ std::tuple<Statement<EnumerationTypeStmt>,
+ std::list<Statement<EnumerationEnumeratorStmt>>,
+ Statement<EndEnumerationTypeStmt>>
+ t;
+};
+
// R773 ac-value -> expr | ac-implied-do
struct AcValue {
struct Triplet { // PGI/Intel extension
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 4c422ac5f471a..72b09e2b89dd6 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -497,6 +497,10 @@ class DerivedTypeDetails {
const SymbolVector ¶mDeclOrder() const { return paramDeclOrder_; }
bool sequence() const { return sequence_; }
bool isDECStructure() const { return isDECStructure_; }
+ bool isEnumerationType() const { return isEnumerationType_; }
+ void set_isEnumerationType(bool x = true) { isEnumerationType_ = x; }
+ int enumeratorCount() const { return enumeratorCount_; }
+ void set_enumeratorCount(int n) { enumeratorCount_ = n; }
std::map<SourceName, SymbolRef> &finals() { return finals_; }
const std::map<SourceName, SymbolRef> &finals() const { return finals_; }
bool isForwardReferenced() const { return isForwardReferenced_; }
@@ -548,6 +552,10 @@ class DerivedTypeDetails {
bool isForwardReferenced_{false};
std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
+ // These fields are only used if the derived type is an enumeration type.
+ bool isEnumerationType_{false};
+ int enumeratorCount_{0};
+
friend llvm::raw_ostream &operator<<(
llvm::raw_ostream &, const DerivedTypeDetails &);
};
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index d2e2be2548d2e..808e885b2b3c5 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -197,6 +197,8 @@ bool IsExternal(const Symbol &);
bool IsModuleProcedure(const Symbol &);
bool HasCoarray(const parser::Expr &);
bool IsAssumedType(const Symbol &);
+bool IsEnumerationType(const Symbol &);
+bool IsEnumerationType(const DerivedTypeSpec &);
bool IsPolymorphic(const Symbol &);
bool IsUnlimitedPolymorphic(const Symbol &);
bool IsPolymorphicAllocatable(const Symbol &);
diff --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h
index 3a07b6ee2ec1c..9d0a2427c1b6f 100644
--- a/flang/include/flang/Semantics/type.h
+++ b/flang/include/flang/Semantics/type.h
@@ -263,7 +263,13 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ArraySpec &);
// The name may not match the symbol's name in case of a USE rename.
class DerivedTypeSpec {
public:
- enum class Category { DerivedType, IntrinsicVector, PairVector, QuadVector };
+ enum class Category {
+ DerivedType,
+ IntrinsicVector,
+ PairVector,
+ QuadVector,
+ EnumerationType
+ };
using RawParameter = std::pair<const parser::Keyword *, ParamValue>;
using RawParameters = std::vector<RawParameter>;
@@ -335,6 +341,9 @@ class DerivedTypeSpec {
return category_ == Category::IntrinsicVector ||
category_ == Category::PairVector || category_ == Category::QuadVector;
}
+ bool IsEnumerationType() const {
+ return category_ == Category::EnumerationType;
+ }
private:
SourceName name_;
diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp
index 99dc8b1e5c676..7c1fc804d69ef 100644
--- a/flang/lib/Evaluate/type.cpp
+++ b/flang/lib/Evaluate/type.cpp
@@ -158,8 +158,9 @@ std::size_t DynamicType::GetAlignment(
switch (GetDerivedTypeSpec().category()) {
SWITCH_COVERS_ALL_CASES
case semantics::DerivedTypeSpec::Category::DerivedType:
- if (derived_ && derived_->scope()) {
- return derived_->scope()->alignment().value_or(1);
+ case semantics::DerivedTypeSpec::Category::EnumerationType:
+ if (derived_ && derived_->GetScope()) {
+ return derived_->GetScope()->alignment().value_or(1);
}
break;
case semantics::DerivedTypeSpec::Category::IntrinsicVector:
@@ -199,9 +200,9 @@ std::optional<Expr<SubscriptInteger>> DynamicType::MeasureSizeInBytes(
}
break;
case TypeCategory::Derived:
- if (!IsPolymorphic() && derived_ && derived_->scope()) {
- auto size{derived_->scope()->size()};
- auto align{aligned ? derived_->scope()->alignment().value_or(0) : 0};
+ if (!IsPolymorphic() && derived_ && derived_->GetScope()) {
+ auto size{derived_->GetScope()->size()};
+ auto align{aligned ? derived_->GetScope()->alignment().value_or(0) : 0};
auto alignedSize{align > 0 ? ((size + align - 1) / align) * align : size};
return Expr<SubscriptInteger>{
static_cast<ConstantSubscript>(alignedSize)};
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 0d343968374f0..28d2c1be5e6fc 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -371,6 +371,9 @@ struct TypeBuilderImpl {
mlir::IntegerType::get(context, 1));
case (Fortran::semantics::DerivedTypeSpec::Category::DerivedType):
Fortran::common::die("Vector element type not implemented");
+ case (Fortran::semantics::DerivedTypeSpec::Category::EnumerationType):
+ Fortran::common::die(
+ "Vector element type not implemented for enumeration");
}
}
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index b67475074217c..df7c25de52faf 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -669,6 +669,35 @@ TYPE_PARSER(
TYPE_PARSER(recovery("END ENUM"_tok, constructEndStmtErrorRecovery) >>
construct<EndEnumStmt>())
+// F2023 R766 enumeration-type-def ->
+// enumeration-type-stmt
+// enumeration-enumerator-stmt [ enumeration-enumerator-stmt ]...
+// end-enumeration-type-stmt
+TYPE_CONTEXT_PARSER("enumeration type definition"_en_US,
+ construct<EnumerationTypeDef>(statement(Parser<EnumerationTypeStmt>{}),
+ some(unambiguousStatement(Parser<EnumerationEnumeratorStmt>{})),
+ statement(Parser<EndEnumerationTypeStmt>{})))
+
+// F2023 R767 enumeration-type-stmt ->
+// ENUMERATION TYPE [ [ , access-spec ] :: ] enumeration-type-name
+TYPE_CONTEXT_PARSER("ENUMERATION TYPE statement"_en_US,
+ construct<EnumerationTypeStmt>(
+ "ENUMERATION TYPE" >> maybe("," >> accessSpec) / "::", name) ||
+ construct<EnumerationTypeStmt>(
+ "ENUMERATION TYPE" >> construct<std::optional<AccessSpec>>(), name))
+
+// F2023 R768 enumeration-enumerator-stmt -> ENUMERATOR [ :: ]
+// enumerator-name-list
+// (Note: distinct from R761 enumerator-def-stmt — no "= expr" allowed here)
+TYPE_CONTEXT_PARSER("ENUMERATOR statement in ENUMERATION TYPE"_en_US,
+ construct<EnumerationEnumeratorStmt>(
+ "ENUMERATOR" >> maybe("::"_tok) >> nonemptyList(name)))
+
+// F2023 R769 end-enumeration-type-stmt ->
+// END ENUMERATION TYPE [ enumeration-type-name ]
+TYPE_PARSER(construct<EndEnumerationTypeStmt>(recovery(
+ "END ENUMERATION TYPE" >> maybe(name), namedConstructEndStmtErrorRecovery)))
+
// R801 type-declaration-stmt ->
// declaration-type-spec [[, attr-spec]... ::] entity-decl-list
constexpr auto entityDeclWithoutEqInit{
diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index b26603b5aea45..8a81ce6243711 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -183,12 +183,14 @@ constexpr auto limitedSpecificationPart{inContext("specification part"_en_US,
implicitPart, many(limitedDeclarationConstruct)))};
// R508 specification-construct ->
-// derived-type-def | enum-def | generic-stmt | interface-block |
-// parameter-stmt | procedure-declaration-stmt |
+// derived-type-def | enum-def | enumeration-type-def | generic-stmt |
+// interface-block | parameter-stmt | procedure-declaration-stmt |
// other-specification-stmt | type-declaration-stmt
TYPE_CONTEXT_PARSER("specification construct"_en_US,
first(construct<SpecificationConstruct>(indirect(Parser<DerivedTypeDef>{})),
construct<SpecificationConstruct>(indirect(Parser<EnumDef>{})),
+ construct<SpecificationConstruct>(
+ indirect(Parser<EnumerationTypeDef>{})),
construct<SpecificationConstruct>(
statement(indirect(Parser<GenericStmt>{}))),
construct<SpecificationConstruct>(indirect(interfaceBlock)),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 5ddd0cfc3a1ef..fdb3076f9559c 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -425,6 +425,22 @@ class UnparseVisitor {
void Post(const EndEnumStmt &) { // R763
Outdent(), Word("END ENUM");
}
+ void Unparse(const EnumerationTypeStmt &x) { // F2023 R767
+ Word("ENUMERATION TYPE");
+ Walk(", ", std::get<std::optional<AccessSpec>>(x.t), " :: ");
+ if (!std::get<std::optional<AccessSpec>>(x.t)) {
+ Word(" :: ");
+ }
+ Walk(std::get<Name>(x.t));
+ Indent();
+ }
+ void Unparse(const EnumerationEnumeratorStmt &x) { // F2023 R768
+ Word("ENUMERATOR :: "), Walk(x.v, ", ");
+ }
+ void Unparse(const EndEnumerationTypeStmt &x) { // F2023 R769
+ Outdent(), Word("END ENUMERATION TYPE");
+ Walk(" ", x.v);
+ }
void Unparse(const BOZLiteralConstant &x) { // R764 - R767
Put(x.v);
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index e1c1167af1604..13aff743ce0ab 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -995,6 +995,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
bool Pre(const parser::NamedConstant &);
void Post(const parser::EnumDef &);
bool Pre(const parser::Enumerator &);
+ bool Pre(const parser::EnumerationTypeDef &);
bool Pre(const parser::AccessSpec &);
bool Pre(const parser::AsynchronousStmt &);
bool Pre(const parser::ContiguousStmt &);
@@ -5892,6 +5893,12 @@ bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
return false;
}
+bool DeclarationVisitor::Pre(const parser::EnumerationTypeDef &x) {
+ Say(std::get<parser::Statement<parser::EnumerationTypeStmt>>(x.t).source,
+ "F2023 ENUMERATION TYPEs are not yet implemented"_err_en_US);
+ return false;
+}
+
void DeclarationVisitor::Post(const parser::EnumDef &) {
enumerationState_ = EnumeratorState{};
}
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index ed0715a422e78..65c8eb2e3d040 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -580,6 +580,7 @@ llvm::raw_ostream &operator<<(
llvm::raw_ostream &operator<<(
llvm::raw_ostream &os, const DerivedTypeDetails &x) {
DumpBool(os, "sequence", x.sequence_);
+ DumpBool(os, "isEnumerationType", x.isEnumerationType_);
DumpList(os, "components", x.componentNames_);
return os;
}
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index e0e8727251ed8..325d84d4a3349 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -1070,6 +1070,17 @@ bool IsAssumedType(const Symbol &symbol) {
return false;
}
+bool IsEnumerationType(const Symbol &symbol) {
+ if (const auto *details{symbol.detailsIf<DerivedTypeDetails>()}) {
+ return details->isEnumerationType();
+ }
+ return false;
+}
+
+bool IsEnumerationType(const DerivedTypeSpec &derived) {
+ return derived.IsEnumerationType();
+}
+
bool IsPolymorphic(const Symbol &symbol) {
if (const DeclTypeSpec * type{symbol.GetType()}) {
return type->IsPolymorphic();
diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp
index bb8fddbffd945..9b91c32adbc76 100644
--- a/flang/lib/Semantics/type.cpp
+++ b/flang/lib/Semantics/type.cpp
@@ -355,6 +355,20 @@ void DerivedTypeSpec::Instantiate(Scope &containingScope) {
return;
}
instantiated_ = true;
+
+ if (IsEnumerationType()) {
+ // Enumeration types have no components, no parameters, and need
+ // no instantiation, but scope_ must be set so that callers of
+ // scope() (e.g., GetAlignment, MeasureSizeInBytes) can access
+ // the type's size and alignment.
+ scope_ = typeSymbol_.scope();
+ Scope &mutableTypeScope{const_cast<Scope &>(*scope_)};
+ if (!mutableTypeScope.derivedTypeSpec()) {
+ mutableTypeScope.set_derivedTypeSpec(*this);
+ }
+ return;
+ }
+
auto &context{containingScope.context()};
auto &foldingContext{context.foldingContext()};
if (IsForwardReferenced()) {
@@ -738,6 +752,8 @@ std::string DerivedTypeSpec::VectorTypeAsFortran() const {
break;
case (Fortran::semantics::DerivedTypeSpec::Category::DerivedType):
Fortran::common::die("Vector element type not implemented");
+ case (Fortran::semantics::DerivedTypeSpec::Category::EnumerationType):
+ Fortran::common::die("Vector element type not implemented for enumeration");
}
return buf;
}
@@ -745,6 +761,10 @@ std::string DerivedTypeSpec::VectorTypeAsFortran() const {
std::string DerivedTypeSpec::AsFortran() const {
std::string buf;
llvm::raw_string_ostream ss{buf};
+ if (IsEnumerationType()) {
+ ss << "ENUMERATION TYPE :: " << originalTypeSymbol_.name();
+ return buf;
+ }
ss << originalTypeSymbol_.name();
if (!rawParameters_.empty()) {
CHECK(parameters_.empty());
>From 0cc39bbadb352e42a6157174275fb659d665dea7 Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Thu, 16 Apr 2026 15:06:39 -0500
Subject: [PATCH 2/2] Adding a parser test.
---
flang/test/Parser/enumeration-type.f90 | 113 +++++++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 flang/test/Parser/enumeration-type.f90
diff --git a/flang/test/Parser/enumeration-type.f90 b/flang/test/Parser/enumeration-type.f90
new file mode 100644
index 0000000000000..e984c127bb4e0
--- /dev/null
+++ b/flang/test/Parser/enumeration-type.f90
@@ -0,0 +1,113 @@
+! RUN: %flang_fc1 -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s -check-prefix=TREE
+
+! Test parsing of F2023 enumeration type definitions (R766-R769)
+
+module m
+ ! Basic enumeration type with double-colon
+ ! CHECK: ENUMERATION TYPE :: color
+ ! CHECK: ENUMERATOR :: red, green, blue
+ ! CHECK: END ENUMERATION TYPE color
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: Name = 'color'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'red'
+ ! TREE: Name = 'green'
+ ! TREE: Name = 'blue'
+ ! TREE: EndEnumerationTypeStmt
+ ! TREE: Name = 'color'
+ enumeration type :: color
+ enumerator :: red, green, blue
+ end enumeration type color
+
+ ! Without double-colon on ENUMERATION TYPE statement
+ ! CHECK: ENUMERATION TYPE :: direction
+ ! CHECK: ENUMERATOR :: north, south, east, west
+ ! CHECK: END ENUMERATION TYPE direction
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: Name = 'direction'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'north'
+ ! TREE: Name = 'south'
+ ! TREE: Name = 'east'
+ ! TREE: Name = 'west'
+ ! TREE: EndEnumerationTypeStmt
+ ! TREE: Name = 'direction'
+ enumeration type direction
+ enumerator north, south, east, west
+ end enumeration type direction
+
+ ! With access-spec (PUBLIC)
+ ! CHECK: ENUMERATION TYPE, PUBLIC :: priority
+ ! CHECK: ENUMERATOR :: low, medium, high
+ ! CHECK: END ENUMERATION TYPE priority
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: AccessSpec -> Kind = Public
+ ! TREE: Name = 'priority'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'low'
+ ! TREE: Name = 'medium'
+ ! TREE: Name = 'high'
+ ! TREE: EndEnumerationTypeStmt
+ enumeration type, public :: priority
+ enumerator :: low, medium, high
+ end enumeration type priority
+
+ ! With access-spec (PRIVATE)
+ ! CHECK: ENUMERATION TYPE, PRIVATE :: internal_state
+ ! CHECK: ENUMERATOR :: idle, running
+ ! CHECK: END ENUMERATION TYPE internal_state
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: AccessSpec -> Kind = Private
+ ! TREE: Name = 'internal_state'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'idle'
+ ! TREE: Name = 'running'
+ ! TREE: EndEnumerationTypeStmt
+ enumeration type, private :: internal_state
+ enumerator :: idle, running
+ end enumeration type internal_state
+
+ ! Multiple ENUMERATOR statements
+ ! CHECK: ENUMERATION TYPE :: season
+ ! CHECK: ENUMERATOR :: spring
+ ! CHECK: ENUMERATOR :: summer
+ ! CHECK: ENUMERATOR :: autumn, winter
+ ! CHECK: END ENUMERATION TYPE season
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: Name = 'season'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'spring'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'summer'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'autumn'
+ ! TREE: Name = 'winter'
+ ! TREE: EndEnumerationTypeStmt
+ ! TREE: Name = 'season'
+ enumeration type :: season
+ enumerator :: spring
+ enumerator :: summer
+ enumerator :: autumn, winter
+ end enumeration type season
+
+ ! End statement without name
+ ! CHECK: ENUMERATION TYPE :: simple
+ ! CHECK: ENUMERATOR :: a, b
+ ! CHECK: END ENUMERATION TYPE
+ ! TREE: EnumerationTypeDef
+ ! TREE: EnumerationTypeStmt
+ ! TREE: Name = 'simple'
+ ! TREE: EnumerationEnumeratorStmt
+ ! TREE: Name = 'a'
+ ! TREE: Name = 'b'
+ ! TREE: EndEnumerationTypeStmt
+ enumeration type :: simple
+ enumerator :: a, b
+ end enumeration type
+end module
More information about the flang-commits
mailing list