diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-02 10:24:44 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-02 10:24:44 +0200 |
commit | 5153b42878bfb1b90ee1933a8f4aeca87779e971 (patch) | |
tree | 7bfaa569b3287acf6bc3538dc2f0488629d028e4 | |
parent | 3db9d7f1bc896e3d1db84cc612c0bd02257d21d6 (diff) |
adds type walker
-rw-r--r-- | gcc/type-walker.hpp | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/gcc/type-walker.hpp b/gcc/type-walker.hpp new file mode 100644 index 00000000000..61d3bec66dc --- /dev/null +++ b/gcc/type-walker.hpp @@ -0,0 +1,391 @@ +#pragma once + +#include "types-inlines.h" +#include <set> + +class TypeWalker { +private: + typedef std::set<const_tree> tset_t; + tset_t tset; + + void _walk(const_tree t, tset_t &tset); + + void _walk_wrapper(const_tree t, tset_t &tset); + void _walk_record_or_union(const_tree t, tset_t &tset); + void _walk_function_or_method(const_tree t, tset_t &tset); + + virtual void _walk_void_pre(const_tree t) {}; + void walk_void(const_tree t, tset_t &tset); + void _walk_void(const_tree t, tset_t &tset); + virtual void _walk_void_post(const_tree t) {}; + virtual void _walk_integer_pre(const_tree t) {}; + void walk_integer(const_tree t, tset_t &tset); + void _walk_integer(const_tree t, tset_t &tset); + virtual void _walk_integer_post(const_tree t) {}; + virtual void _walk_real_pre(const_tree t) {}; + void walk_real(const_tree t, tset_t &tset); + void _walk_real(const_tree t, tset_t &tset); + virtual void _walk_real_post(const_tree t) {}; + virtual void _walk_fixed_point_pre(const_tree t) {}; + void walk_fixed_point(const_tree t, tset_t &tset); + void _walk_fixed_point(const_tree t, tset_t &tset); + virtual void _walk_fixed_point_post(const_tree t) {}; + virtual void _walk_complex_pre(const_tree t) {}; + void _walk_complex(const_tree t, tset &tset); + void walk_complex(const_tree t, tset_t &tset); + virtual void _walk_complex_post(const_tree t) {}; + virtual void _walk_enumeral_pre(const_tree t) {}; + void walk_enumeral(const_tree t, tset_t &tset); + void _walk_enumeral(const_tree t, tset_t &tset); + virtual void _walk_enumeral_post(const_tree t) {}; + virtual void _walk_boolean_pre(const_tree t) {}; + void walk_boolean(const_tree t, tset_t &tset); + void _walk_boolean(const_tree t, tset_t &tset); + virtual void _walk_boolean_post(const_tree t) {}; + virtual void _walk_offset_pre(const_tree t) {}; + void walk_offset(const_tree t, tset_t &tset); + void _walk_offset(const_tree t, tset_t &tset); + virtual void _walk_offset_post(const_tree t) {}; + virtual void _walk_record_pre(const_tree t) {}; + void walk_record(const_tree t, tset_t &tset); + void _walk_record(const_tree t, tset_t &tset); + virtual void _walk_record_post(const_tree t) {}; + virtual void _walk_pointer_pre(const_tree t) {}; + void walk_pointer(const_tree t, tset_t &tset); + void _walk_pointer(const_tree t, tset_t &tset); + virtual void _walk_pointer_post(const_tree t) {}; + virtual void _walk_reference_pre(const_tree t) {}; + void walk_reference(const_tree t, tset_t &tset); + void _walk_reference(const_tree t, tset_t &tset); + virtual void _walk_reference_post(const_tree t) {}; + virtual void _walk_array_pre(const_tree t) {}; + void walk_array(const_tree t, tset_t &tset); + void _walk_array(const_tree t, tset_t &tset); + virtual void _walk_array_post(const_tree t) {}; + virtual void _walk_union_pre(const_tree t) {}; + void walk_union(const_tree t, tset_t &tset); + void _walk_union(const_tree t, tset_t &tset); + virtual void _walk_union_post(const_tree t) {}; + virtual void _walk_function_pre(const_tree t) {}; + void walk_function(const_tree t, tset_t &tset); + void _walk_function(const_tree t, tset_t &tset); + virtual void _walk_function_post(const_tree t) {}; + virtual void _walk_method_pre(const_tree t) {}; + void walk_method(const_tree t, tset_t &tset); + void _walk_method(const_tree t, tset_t &tset); + virtual void _walk_method_post(const_tree t) {}; +public: + void walk(const_tree t); + TypeWalker() {}; +}; + +void +TypeWalker::walk(const_tree t) +{ + gcc_assert(t); + this->tset.clear(); + this->_walk(t, this->tset); +} + +void +TypeWalker::_walk(const_tree type, tset_t &tset) +{ + gcc_assert(type); + // Have we encountered this type before? If so, we are likely + // recurring... + const bool in_set = tset.find(type) != tset.end(); + if (in_set) return; + + tset.insert(type); + const enum tree_code code = TREE_CODE(type); + switch (code) + { + case VOID_TYPE: + this->walk_void(type, tset); + break; + case INTEGER_TYPE: + this->walk_integer(type, tset); + break; + case REAL_TYPE: + this->walk_real(type, tset); + break; + case FIXED_POINT_TYPE: + this->walk_fixed_point(type, tset); + break; + case COMPLEX_TYPE: + this->walk_complex(type, tset); + break; + case ENUMERAL_TYPE: + this->walk_enumeral(type, tset); + break; + case BOOLEAN_TYPE: + this->walk_boolean(type, tset); + break; + case OFFSET_TYPE: + this->walk_offset(type, tset); + break; + case RECORD_TYPE: + this->walk_record(type, tset); + break; + case POINTER_TYPE: + this->walk_pointer(type, tset); + break; + case REFERENCE_TYPE: + this->walk_reference(type, tset); + break; + case ARRAY_TYPE: + this->walk_array(type, tset); + break; + case UNION_TYPE: + this->walk_union(type, tset); + break; + case FUNCTION_TYPE: + this->walk_function(type, tset); + break; + case METHOD_TYPE: + this->walk_method(type, tset); + break; + case QUAL_UNION_TYPE: + case LANG_TYPE: + default: + gcc_unreachable(); + break; + } + + tset.clear(type); +} + +void +TypeWalker::walk_void(const_tree t, tset_t &tset) +{ + assert_is_type(t, VOID_TYPE); + _walk_void_pre(t); + _walk_void(t, tset); + _walk_void_post(t); +} + +void +TypeWalker::_walk_void(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_integer(const_tree t, tset_t &tset) +{ + assert_is_type(t, INTEGER_TYPE); + _walk_integer_pre(t); + _walk_integer(t, tset); + _walk_integer_post(t); +} + +void +TypeWalker::_walk_integer(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_real(const_tree t, tset_t &tset) +{ + assert_is_type(t, REAL_TYPE); + _walk_real_pre(t); + _walk_real(t, tset); + _walk_real_post(t); +} + +void +TypeWalker::_walk_real(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_boolean(const_tree t, tset_t &tset) +{ + assert_is_type(t, BOOLEAN_TYPE); + _walk_boolean_pre(t); + _walk_boolean(t, tset); + _walk_boolean_post(t); +} + +void +TypeWalker::_walk_boolean(const_tree t, tset &tset) {}; + +void +TypeWalker::walk_offset(const_tree t, tset_t &tset) +{ + assert_is_type(t, OFFSET_TYPE); + _walk_offset_pre(t); + _walk_offset(t, tset); + _walk_offset_post(t); +} + +void +TypeWalker::walk_offset(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_fixed_point(const_tree t, tset_t &tset) +{ + assert_is_type(t, FIXED_POINT); + _walk_fixed_point_pre(t); + _walk_fixed_point(t, tset); + _walk_fixed_point_post(t); +} + +void +TypeWalker::walk_fixed_point(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_complex(const_tree t, tset_t &tset) +{ + assert_is_type(t, COMPLEX_TYPE); + _walk_complex_pre(t); + _walk_complex(t, tset); + _walk_complex_post(t); +} + +void +TypeWalker::walk_complex(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_enumeral(const_tree t, tset_t &tset) +{ + assert_is_type(t, ENUMERAL_TYPE); + _walk_enumeral_pre(t); + _walk_enumeral(t, tset); + _walk_enumeral_post(t); +} + +void +TypeWalker::walk_enumeral(const_tree t, tset_t &tset) {}; + +void +TypeWalker::walk_pointer(const_tree t, tset_t &tset) +{ + assert_is_type(t, POINTER_TYPE); + _walk_pointer_pre(t); + _walk_pointer(t, tset); + _walk_pointer_post(t); +} + +void +TypeWalker::_walk_pointer(const_tree t, tset_t &tset) +{ + _walk_wrapper(t, tset); +} + +void +TypeWalker::walk_reference(const_tree t, tset_t &tset) +{ + assert_is_type(t, REFERENCE_TYPE); + _walk_reference_pre(t); + _walk_reference(t, tset); + _walk_reference_post(t); +} + +void +TypeWalker::_walk_reference(const_tree t, tset_t &tset) +{ + _walk_wrapper(t, tset); +} + +void +TypeWalker::walk_array(const_tree t, tset_t &tset) +{ + assert_is_type(t, ARRAY_TYPE); + _walk_array_pre(t); + _walk_array(t, tset); + _walk_array_post(t); +} + +void +TypeWalker::_walk_array(const_tree t, tset_t &tset) +{ + _walk_wrapper(t, tset); +} + +void +TypeWalker::_walk_wrapper(const_tree t, tset_t &tset) +{ + const_tree inner_type = TREE_TYPE(t); + gcc_assert(inner_type); + _walk(inner_type, tset); +} + +void +TypeWalker::walk_record(const_tree t, tset_t &tset) +{ + assert_is_type(t, RECORD_TYPE); + _walk_record_pre(t); + _walk_record(t, tset); + _walk_record_post(t); +} + +void +TypeWalker::_walk_record(const_tree t, tset_t &tset) +{ + _walk_record_or_union(t, tset); +} + +void +TypeWalker::walk_union(const_tree t, tset_t &tset) +{ + assert_is_type(t, UNION_TYPE); + _walk_union_pre(t); + _walk_union(t, tset); + _walk_union_post(t); +} + +void +TypeWalker::walk_union(const_tree t, tset_t &tset) +{ + _walk_record_or_union(t, tset); +} + +void +TypeWalker::_walk_record_or_union(const_tree t, tset_t &tset) +{ + for (tree field = TYPE_FIELDS(t); field; field = DECL_CHAIN(field)) + { + const_tree field_type = TREE_TYPE(field); + gcc_assert(field_type); + _walk(field_type, tset); + } +} + +void +TypeWalker::walk_function(const_tree t, tset_t &tset) +{ + assert_is_type(t, FUNCTION_TYPE); + _walk_function_pre(t); + _walk_function(t, tset); + _walk_union_post(t); +} + +void +TypeWalker::_walk_function(const_tree t, tset_t &tset) +{ + _walk_function_or_method(t, tset); +} + +void +TypeWalker::walk_method(const_tree t, tset_t &tset) +{ + assert_is_type(t, METHOD_TYPE); + _walk_method_pre(t); + _walk_method(t, tset); + _walk_method_post(t); +} + +void +TypeWalker::_walk_method(const_tree t, tset_t &tset) +{ + _walk_function_or_method(t, tset); +} + +void +TypeWalker::_walk_function_or_method(const_tree t, tset_t &tset) +{ + const_tree ret_type = TREE_TYPE(t); + gcc_assert(ret_type); + _walk(ret_type, tset); + + for (tree arg_node = TYPE_ARG_TYPES(t); NULL_TREE != arg_node; arg_node = TREE_CHAIN(arg_node)) + { + tree arg_node_type = TREE_VALUE(arg_node); + gcc_assert(arg_node_type); + _walk(arg_node_type); + } +} |