[flang] Address comment: store current enum value in an int
authorJean Perier <jperier@nvidia.com>
Wed, 28 Aug 2019 11:58:38 +0000 (04:58 -0700)
committerJean Perier <jperier@nvidia.com>
Wed, 28 Aug 2019 11:58:38 +0000 (04:58 -0700)
During enumerator name resolution, instead of keeping the current
enumerator value inside an expression, fold it to an int and keep
it as an int. This is clearer and will be easier if one wants to
provide some enum type size optimization.

Original-commit: flang-compiler/f18@4e49d5396c5ff475b1f329e9fc349cc336574c50
Reviewed-on: https://github.com/flang-compiler/f18/pull/689
Tree-same-pre-rewrite: false

flang/lib/semantics/resolve-names.cc
flang/test/semantics/resolve60.f90

index 3a49c29..1679bf3 100644 (file)
@@ -849,8 +849,7 @@ private:
   // Info about current ENUM
   struct EnumeratorState {
     // Enum value must hold inside a C_INT (7.6.2).
-    using CIntExpr = evaluate::Expr<evaluate::CInteger>;
-    std::optional<CIntExpr> value{CIntExpr{-1}};
+    std::optional<int> value{0};
   } enumerationState_;
 
   bool HandleAttributeStmt(Attr, const std::list<parser::Name> &);
@@ -2735,28 +2734,32 @@ bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
   if (auto &init{std::get<std::optional<parser::ScalarIntConstantExpr>>(
           enumerator.t)}) {
     Walk(*init);  // Resolve names in expression before evaluation.
-    if (MaybeIntExpr expr{EvaluateIntExpr(*init)}) {
+    MaybeIntExpr expr{EvaluateIntExpr(*init)};
+    if (auto value{evaluate::ToInt64(expr)}) {
       // Cast all init expressions to C_INT so that they can then be
       // safely incremented (see 7.6 Note 2).
-      enumerationState_.value =
-          evaluate::ConvertToType<evaluate::CInteger>(std::move(*expr));
+      enumerationState_.value = static_cast<int>(*value);
     } else {
-      // Error in expr, prevent resolution of next enumerators value
+      Say(name,
+          "Enumerator value could not be computed "
+          "from the given expression"_err_en_US);
+      // Prevent resolution of next enumerators value
       enumerationState_.value = std::nullopt;
     }
-  } else if (enumerationState_.value) {
-    enumerationState_.value =
-        FoldExpr(evaluate::Increment(std::move(*enumerationState_.value)));
   }
 
   if (symbol) {
     if (enumerationState_.value.has_value()) {
-      symbol->get<ObjectEntityDetails>().set_init(
-          SomeExpr{*enumerationState_.value});
+      symbol->get<ObjectEntityDetails>().set_init(SomeExpr{
+          evaluate::Expr<evaluate::CInteger>{*enumerationState_.value}});
     } else {
       context().SetError(*symbol);
     }
   }
+
+  if (enumerationState_.value) {
+    (*enumerationState_.value)++;
+  }
   return false;
 }
 
index 8f54ab9..d4b20a2 100644 (file)
@@ -44,6 +44,7 @@
   end enum
 
   enum, bind(C)
+    !ERROR: Enumerator value could not be computed from the given expression
     !ERROR: Must be a constant value
     enumerator :: wrong = 0/0
   end enum