#include "config.h" #include "system.h" #include "coretypes.h" #include "backend.h" #include "tree.h" #include "gimple-expr.h" #include "predict.h" #include "alloc-pool.h" #include "tree-pass.h" #include "cgraph.h" #include "diagnostic.h" #include "fold-const.h" #include "gimple-fold.h" #include "symbol-summary.h" #include "tree-vrp.h" #include "ipa-prop.h" #include "tree-pretty-print.h" #include "tree-inline.h" #include "ipa-fnsummary.h" #include "ipa-utils.h" #include "tree-ssa-ccp.h" #include "stringpool.h" #include "attribs.h" #include "tree-ssa-alias.h" #include "tree-ssanames.h" #include "gimple.h" #include "cfg.h" #include "gimple-iterator.h" #include "gimple-ssa.h" #include "type-walker.hpp" #include "types-inlines.h" 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; const bool _is_memoized = is_memoized(type); if (_is_memoized) 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.erase(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_t &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_TYPE); _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)) { gcc_assert(field); walk_field(field, tset); } } void TypeWalker::walk_field(const_tree t, tset_t &tset) { _walk_field_pre(t); _walk_field(t, tset); _walk_field_post(t); } void TypeWalker::_walk_field(const_tree t, tset_t &tset) { const_tree inner_type = TREE_TYPE(t); gcc_assert(inner_type); _walk(inner_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_function_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); walk_return(ret_type, tset); walk_args(t, tset); } void TypeWalker::walk_return(const_tree t, tset_t &tset) { _walk_return_pre(t); _walk_return(t, tset); _walk_return_post(t); } void TypeWalker::_walk_return(const_tree t, tset_t &tset) { _walk(t, tset); } void TypeWalker::walk_args(const_tree t, tset_t &tset) { _walk_args_pre(t); _walk_args(t, tset); _walk_args_post(t); } void TypeWalker::_walk_args(const_tree t, tset_t &tset) { assert_is_type(t, FUNCTION_TYPE); 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(arg_node_type, tset); } } void TypeWalker::walk_arg(const_tree t, tset_t &tset) { _walk_arg_pre(t); _walk_arg(t, tset); _walk_arg_post(t); } void TypeWalker::_walk_arg(const_tree t, tset_t &tset) { _walk(t, tset); }