This commit implements a full-featured iterator for the riscv_subset_list, that it able to use range-based-for-loop.
That could simplfy the code in the future, and make it more readable, also more compatible with standard C++ containers. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Use range-based-for-loop. * config/riscv/riscv-subset.h (riscv_subset_list::iterator): New. (riscv_subset_list::const_iterator): New. --- gcc/config/riscv/riscv-c.cc | 18 ++++------ gcc/config/riscv/riscv-subset.h | 62 +++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 1ff1968f6d8..d2c0af35955 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -239,26 +239,22 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile) size_t max_ext_len = 0; /* Figure out the max length of extension name for reserving buffer. */ - for (const riscv_subset_t *subset = subset_list->begin (); - subset != subset_list->end (); - subset = subset->next) - max_ext_len = MAX (max_ext_len, subset->name.length ()); + for (auto &subset : *subset_list) + max_ext_len = MAX (max_ext_len, subset.name.length ()); char *buf = (char *)alloca (max_ext_len + 10 /* For __riscv_ and '\0'. */); - for (const riscv_subset_t *subset = subset_list->begin (); - subset != subset_list->end (); - subset = subset->next) + for (auto &subset : *subset_list) { - int version_value = riscv_ext_version_value (subset->major_version, - subset->minor_version); + int version_value = riscv_ext_version_value (subset.major_version, + subset.minor_version); /* Special rule for zicsr and zifencei, it's used for ISA spec 2.2 or earlier. */ - if ((subset->name == "zicsr" || subset->name == "zifencei") + if ((subset.name == "zicsr" || subset.name == "zifencei") && version_value == 0) version_value = riscv_ext_version_value (2, 0); - sprintf (buf, "__riscv_%s", subset->name.c_str ()); + sprintf (buf, "__riscv_%s", subset.name.c_str ()); builtin_define_with_int_value (buf, version_value); } } diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index c5d9fab4de9..a35537d7754 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -109,9 +109,6 @@ public: static riscv_subset_list *parse (const char *, location_t); const char *parse_single_ext (const char *, bool exact_single_p = true); - const riscv_subset_t *begin () const {return m_head;}; - const riscv_subset_t *end () const {return NULL;}; - int match_score (riscv_subset_list *) const; void set_loc (location_t); @@ -119,6 +116,65 @@ public: void set_allow_adding_dup (bool v) { m_allow_adding_dup = v; } void finalize (); + + class iterator + { + public: + explicit iterator(riscv_subset_t *node) : m_node(node) {} + + riscv_subset_t &operator*() const { return *m_node; } + riscv_subset_t *operator->() const { return m_node; } + + iterator &operator++() + { + if (m_node) + m_node = m_node->next; + return *this; + } + + bool operator!=(const iterator &other) const + { + return m_node != other.m_node; + } + + bool operator==(const iterator &other) const + { + return m_node == other.m_node; + } + + private: + riscv_subset_t *m_node; + }; + + iterator begin() { return iterator(m_head); } + iterator end() { return iterator(nullptr); } + + class const_iterator + { + public: + explicit const_iterator(const riscv_subset_t *node) : m_node(node) {} + + const riscv_subset_t &operator*() const { return *m_node; } + const riscv_subset_t *operator->() const { return m_node; } + + const_iterator &operator++() + { + if (m_node) + m_node = m_node->next; + return *this; + } + + bool operator!=(const const_iterator &other) const + { + return m_node != other.m_node; + } + + private: + const riscv_subset_t *m_node; + }; + + const_iterator begin() const { return const_iterator(m_head); } + const_iterator end() const { return const_iterator(nullptr); } }; extern const riscv_subset_list *riscv_cmdline_subset_list (void); -- 2.34.1