Introduce classes for Fortran bound intrinsics
authorTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:27:57 +0000 (07:27 -0700)
committerTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:28:30 +0000 (07:28 -0700)
This adds class fortran_bound_1arg and fortran_bound_2arg, to
implement the Fortran lbound and ubound intrinsics.

gdb/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

* f-lang.c (fortran_bound_1arg::evaluate)
(fortran_bound_2arg::evaluate): New methods.
* f-exp.h (class fortran_bound_1arg, class fortran_bound_2arg):
New.

gdb/ChangeLog
gdb/f-exp.h
gdb/f-lang.c

index 66f770539188569aa8dcc7d743528d9738e7ac9c..6f3037c8c2804a35e40f228a4f2f858e26c23b49 100644 (file)
@@ -1,3 +1,10 @@
+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * f-lang.c (fortran_bound_1arg::evaluate)
+       (fortran_bound_2arg::evaluate): New methods.
+       * f-exp.h (class fortran_bound_1arg, class fortran_bound_2arg):
+       New.
+
 2021-03-08  Tom Tromey  <tom@tromey.com>
 
        * expop.h (class unop_addr_operation) <get_expression>: New
index b569c33ad9cbee207e4bcff7f8dd73a34c5e3b79..e1d351a2bb421c915ac754bba9447eca3a91a0a0 100644 (file)
@@ -159,6 +159,38 @@ private:
                         enum noside noside);
 };
 
+/* Single-argument form of Fortran ubound/lbound intrinsics.  */
+class fortran_bound_1arg
+  : public tuple_holding_operation<exp_opcode, operation_up>
+{
+public:
+
+  using tuple_holding_operation::tuple_holding_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return std::get<0> (m_storage); }
+};
+
+/* Two-argument form of Fortran ubound/lbound intrinsics.  */
+class fortran_bound_2arg
+  : public tuple_holding_operation<exp_opcode, operation_up, operation_up>
+{
+public:
+
+  using tuple_holding_operation::tuple_holding_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return std::get<0> (m_storage); }
+};
+
 } /* namespace expr */
 
 #endif /* FORTRAN_EXP_H */
index 6f7217dc94af453770570baceff5ffeb9c592f05..dcd7c48bbcfec4b6a4395ad69017f3bfbdc874b6 100644 (file)
@@ -1865,6 +1865,40 @@ fortran_undetermined::evaluate (struct type *expect_type,
     }
 }
 
+value *
+fortran_bound_1arg::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
+{
+  bool lbound_p = std::get<0> (m_storage) == FORTRAN_LBOUND;
+  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  fortran_require_array (value_type (arg1), lbound_p);
+  return fortran_bounds_all_dims (lbound_p, exp->gdbarch, arg1);
+}
+
+value *
+fortran_bound_2arg::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
+{
+  bool lbound_p = std::get<0> (m_storage) == FORTRAN_LBOUND;
+  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  fortran_require_array (value_type (arg1), lbound_p);
+
+  /* User asked for the bounds of a specific dimension of the array.  */
+  value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+  struct type *type = check_typedef (value_type (arg2));
+  if (type->code () != TYPE_CODE_INT)
+    {
+      if (lbound_p)
+       error (_("LBOUND second argument should be an integer"));
+      else
+       error (_("UBOUND second argument should be an integer"));
+    }
+
+  return fortran_bounds_for_dimension (lbound_p, exp->gdbarch, arg1, arg2);
+}
+
 } /* namespace expr */
 
 /* Special expression lengths for Fortran.  */