summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-02 16:53:52 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-02 16:53:52 +0200
commitb13fddcb84484838ab31e3bc29263a2da3197cd9 (patch)
tree6eb0fd153a06378abbccd6c6f7e22fe9f765016a
parent71e7fa841fc569af0d7fabf3303a26df84eefcc6 (diff)
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/collect-types.c377
-rw-r--r--gcc/collect-types.h2
-rw-r--r--gcc/ipa-hello-world.c2
-rw-r--r--gcc/ipa-type-collector.c21
-rw-r--r--gcc/name-types.c1
-rw-r--r--gcc/name-types.h4
-rw-r--r--gcc/type-collector.c237
-rw-r--r--gcc/type-collector.hpp49
-rw-r--r--gcc/type-stringifier.hpp113
-rw-r--r--gcc/type-walker.c402
-rw-r--r--gcc/type-walker.hpp333
12 files changed, 821 insertions, 722 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a9c188e6e03..da6f7fb4f93 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1401,6 +1401,8 @@ OBJS = \
internal-fn.o \
ipa-hello-world.o \
ipa-type-collector.o \
+ type-walker.o \
+ type-collector.o \
compare-types.o \
collect-types.o \
name-types.o \
diff --git a/gcc/collect-types.c b/gcc/collect-types.c
index 3ebd6ff975e..da66bb11fa2 100644
--- a/gcc/collect-types.c
+++ b/gcc/collect-types.c
@@ -30,324 +30,29 @@
#include "compare-types.h"
#include "types-inlines.h"
+#include "type-stringifier.hpp"
#include "name-types.h"
#include <set>
#include "collect-types.h"
-static bool filter_boring_types(const_tree type, ptrset_t &);
-
-static bool
-filter_boring_types_wrapper(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- const_tree inner_type = TREE_TYPE(type);
- gcc_assert(inner_type);
- return filter_boring_types(inner_type, types);
-}
-
-static bool
-filter_boring_types_array(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, ARRAY_TYPE);
- return filter_boring_types_wrapper(type, types);
-}
-
-static bool
-filter_boring_types_reference(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, REFERENCE_TYPE);
- return filter_boring_types_wrapper(type, types);
-}
-
-static bool
-filter_boring_types_pointer(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, POINTER_TYPE);
- return filter_boring_types_wrapper(type, types);
-}
-
-static bool
-filter_boring_types_union_or_record(const_tree type, ptrset_t &types)
-{
- const enum tree_code code = TREE_CODE(type);
- const bool is_union = UNION_TYPE == code;
- const bool is_qual_union = QUAL_UNION_TYPE == code;
- const bool is_record = RECORD_TYPE == code;
- const bool is_valid_input = is_union || is_qual_union || is_record;
- gcc_assert(is_valid_input);
-
- bool is_interesting = is_record;
- for (tree field = TYPE_FIELDS(type) ; field ; field = DECL_CHAIN(field))
- {
- // TYPE_FIELDS contains the items contained in this type, each of which can be a FIELD_DECL, VAR_DECL, CONST_DECL, or TYPE_DECL
- const_tree field_type = TREE_TYPE(field);
- gcc_assert(field_type);
- is_interesting |= filter_boring_types(field_type, types);
- }
-
- return !is_interesting;
-}
-
-static bool
-filter_boring_types_record(const_tree type, ptrset_t &types)
-{
- return filter_boring_types_union_or_record(type, types);
-}
-
-static bool
-filter_boring_types_unions(const_tree type, ptrset_t &types)
-{
- return filter_boring_types_union_or_record(type, types);
-}
-
-static bool
-filter_boring_types_union(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, UNION_TYPE);
- return filter_boring_types_unions(type, types);
-}
-
-static bool
-filter_boring_types_qual_union(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, QUAL_UNION_TYPE);
- return filter_boring_types_unions(type, types);
-}
-
-static bool
-filter_boring_types_function_or_method(const_tree type, ptrset_t &types)
-{
- const enum tree_code code = TREE_CODE(type);
- const bool is_function = FUNCTION_TYPE == code;
- const bool is_method = METHOD_TYPE == code;
- const bool is_valid_input = is_function || is_method;
- gcc_assert(is_valid_input);
-
- const_tree ret_type = TREE_TYPE(type);
- gcc_assert(ret_type);
- const bool retval_is_boring = filter_boring_types(ret_type, types);
- //if (!retval_is_boring) return retval_is_boring;
-
- tree arg_node = TYPE_ARG_TYPES(type);
- while (NULL_TREE != arg_node)
- {
- tree arg_node_type = TREE_VALUE(arg_node);
- gcc_assert(arg_node_type);
- const bool arg_is_boring = filter_boring_types(arg_node_type, types);
- arg_node = TREE_CHAIN(arg_node);
- //if (!arg_is_boring) return arg_is_boring;
- }
-
- return true;
-}
-
-static bool
-filter_boring_types_function(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, FUNCTION_TYPE);
- return filter_boring_types_function_or_method(type, types);
-}
-
-static bool
-filter_boring_types_method(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, METHOD_TYPE);
- return filter_boring_types_function_or_method(type, types);
-}
-
-static bool
-filter_boring_types(const_tree type, ptrset_t &types)
-{
- // boring types are those that do not point to
- // a struct
- gcc_assert(type);
-
- // Optimization to speed up the filter.
- // Memoization
- const bool seen_before = types.in_universe(type);
- if (seen_before)
- {
- const bool in_points_to_record = types.in_points_to_record(type);
- const bool in_complement = types.in_complement(type);
- const bool _xor = in_points_to_record != in_complement;
- gcc_assert(_xor);
- return in_complement;
- }
-
-
- bool is_boring = true;
- enum tree_code code = TREE_CODE(type);
- switch (code)
- {
- case VOID_TYPE:
- case INTEGER_TYPE:
- case REAL_TYPE:
- case FIXED_POINT_TYPE:
- case COMPLEX_TYPE:
- case ENUMERAL_TYPE:
- case BOOLEAN_TYPE:
- case OFFSET_TYPE:
- is_boring = true;
- break;
- case ARRAY_TYPE:
- is_boring = filter_boring_types_array(type, types);
- break;
- case RECORD_TYPE:
- is_boring = filter_boring_types_record(type, types);
- is_boring = false;
- break;
- case UNION_TYPE:
- is_boring = filter_boring_types_union(type, types);
- break;
- case QUAL_UNION_TYPE:
- is_boring = filter_boring_types_qual_union(type, types);
- break;
- case REFERENCE_TYPE:
- is_boring = filter_boring_types_reference(type, types);
- break;
- case POINTER_TYPE:
- is_boring = filter_boring_types_pointer(type, types);
- break;
- case FUNCTION_TYPE:
- is_boring = filter_boring_types_function(type, types);
- break;
- case METHOD_TYPE:
- is_boring = filter_boring_types_method(type, types);
- break;
- default:
- log("tree_code: %s\n", get_tree_code_name(code));
- gcc_unreachable();
- break;
- }
-
- // This should be one the two only times we call insert!
- types.insert(type, !is_boring);
-
- return is_boring;
-}
-
-static const unsigned filter_buffer_size = 1;
-typedef bool (*filter_t)(const_tree, ptrset_t&);
-const extern filter_t filter[filter_buffer_size] =
-{
- filter_boring_types,
-};
-
-static void
-collect_types_from_record_or_union_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- const enum tree_code code = TREE_CODE(type);
- const bool is_union = UNION_TYPE == code;
- const bool is_record = RECORD_TYPE == code;
- const bool is_qual_union = QUAL_UNION_TYPE == code;
- const bool is_valid_input = is_record || is_union || is_qual_union;
- gcc_assert(is_valid_input);
-
- for (tree field = TYPE_FIELDS(type) ; field ; field = DECL_CHAIN(field))
- {
- const_tree field_type = TREE_TYPE(field);
- gcc_assert(field_type);
- collect_types(field_type, types);
- }
-}
-
-static void
-collect_types_from_record_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, RECORD_TYPE);
- collect_types_from_record_or_union_type(type, types);
-}
-
-static void
-collect_types_from_union_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, UNION_TYPE);
- collect_types_from_record_or_union_type(type, types);
-}
-
-static void
-collect_types_from_wrapper_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- //assert_is_complete(type);
- const_tree inner_type = TREE_TYPE(type);
- gcc_assert(inner_type);
- collect_types(inner_type, types);
-}
-
-static void
-collect_types_from_pointer_type(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, POINTER_TYPE);
- assert_is_complete(type);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_reference_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, REFERENCE_TYPE);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_array_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, ARRAY_TYPE);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_function_or_method_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- assert_is_complete(type);
- const enum tree_code code = TREE_CODE(type);
- const bool is_function = FUNCTION_TYPE == code;
- const bool is_method = METHOD_TYPE == code;
- const bool is_valid_input = is_function || is_method;
- gcc_assert(is_valid_input);
-
- const_tree ret_type = TREE_TYPE(type);
- gcc_assert(ret_type);
- collect_types(ret_type, types);
-
- tree arg_node = TYPE_ARG_TYPES(type);
- while (NULL_TREE != arg_node)
- {
- tree arg_node_type = TREE_VALUE(arg_node);
- gcc_assert(arg_node_type);
- collect_types(arg_node_type, types);
- arg_node = TREE_CHAIN(arg_node);
- }
-}
-
-static void
-collect_types_from_function_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, FUNCTION_TYPE);
- collect_types_from_function_or_method_type(type, types);
-}
-
-static void
-collect_types_from_method_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, METHOD_TYPE);
- collect_types_from_function_or_method_type(type, types);
-}
void
points_to_record_sets_s::insert(const_tree type, bool in_points_to_record)
{
gcc_assert(type);
this->universe.insert(type);
+ TypeStringifier stringifier;
+ std::string name = stringifier.stringify(type);
+ log("points_to_record %s type %s\n", in_points_to_record ? "t" : "f", name.c_str());
in_points_to_record ? this->points_to_record.insert(type) : this->complement.insert(type);
// let's just double check...
const bool in_points_to_set = this->in_points_to_record(type);
const bool in_complement = this->in_complement(type);
const bool _xor = in_points_to_set != in_complement;
+ if (!_xor) {
+ log("points_to_record %s type %s != %s %s\n", in_points_to_record ? "t" : "f", in_points_to_set ? "t" : "f", in_complement ? "t": "f", name.c_str());
+ }
gcc_assert(_xor);
}
@@ -375,71 +80,3 @@ points_to_record_sets_s::in_complement(const_tree type) const
return seen_before;
}
-void
-collect_types(const_tree type, ptrset_t &types)
-{
- if (!type) return;
-
- // This should be the only case we call to find if
- // we have seen the type before!
- const bool in_set = types.in_universe(type);
- // memoized.
- if (in_set) return;
-
- // we should have filters here
- // such that if we are processing a type
- // which we know somehow that it is not a type we are interested
- // then we just return immediately.
- // maybe even add it to a set of blacklisted types so that we
- // memoize and do things faster...
- bool is_boring = false;
- for (unsigned i = 0; i < filter_buffer_size; i++)
- {
- is_boring |= filter[i](type, types);
- }
-
- const enum tree_code code = TREE_CODE(type);
- switch (code)
- {
- case VOID_TYPE:
- case INTEGER_TYPE:
- case REAL_TYPE:
- case FIXED_POINT_TYPE:
- case COMPLEX_TYPE:
- case ENUMERAL_TYPE:
- case BOOLEAN_TYPE:
- case OFFSET_TYPE:
- // simple cases and we want to allow them
- break;
- case RECORD_TYPE:
- collect_types_from_record_type(type, types);
- break;
- case POINTER_TYPE:
- collect_types_from_pointer_type(type, types);
- break;
- case REFERENCE_TYPE:
- collect_types_from_reference_type(type, types);
- break;
- case ARRAY_TYPE:
- collect_types_from_array_type(type, types);
- break;
- case UNION_TYPE:
- collect_types_from_union_type(type, types);
- break;
- case FUNCTION_TYPE:
- collect_types_from_function_type(type, types);
- break;
- case METHOD_TYPE:
- collect_types_from_method_type(type, types);
- break;
- case QUAL_UNION_TYPE:
- case LANG_TYPE:
- default:
- log("%s\n", get_tree_code_name(code));
- gcc_unreachable();
- break;
- }
-
- // This should be one the two only times we call insert!
- types.insert(type, !is_boring);
-}
diff --git a/gcc/collect-types.h b/gcc/collect-types.h
index c366b321443..1a6126f6a6d 100644
--- a/gcc/collect-types.h
+++ b/gcc/collect-types.h
@@ -18,5 +18,3 @@ struct points_to_record_sets_s {
};
typedef struct points_to_record_sets_s ptrset_t;
-
-extern void collect_types(const_tree type, ptrset_t &ptrset_t);
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
index c8eb7a0ae6a..6d31926eab1 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-hello-world.c
@@ -35,6 +35,7 @@
#include "compare-types.h"
#include "ipa-type-collector.h"
#include "ipa-hello-world.h"
+#include "type-collector.hpp"
#include <map>
#include <vector>
@@ -1033,6 +1034,7 @@ static unsigned int
iphw_execute()
{
ptrset_t types;
+ TypeCollector::ptrset = &types;
collect_types(types);
typemap eacalc; // Escape Analysis Calculation
diff --git a/gcc/ipa-type-collector.c b/gcc/ipa-type-collector.c
index 85dc71b60ed..9638913d1fe 100644
--- a/gcc/ipa-type-collector.c
+++ b/gcc/ipa-type-collector.c
@@ -37,8 +37,10 @@
#include "name-types.h"
#include "ipa-type-collector.h"
+#include "type-collector.hpp"
//#define FUZZ_MODE 1
+static void collect_types(const_tree t);
namespace type_playground {
enum type_comparison_func_enum {
@@ -128,7 +130,7 @@ collect_types_from_leaf_expr(const_tree expr, ptrset_t &types, const enum tree_c
assert_is_type(expr, ex_code);
const_tree type = TREE_TYPE(expr);
gcc_assert(type);
- collect_types(type, types);
+ collect_types(type);
}
static void
@@ -285,7 +287,7 @@ collect_types_from_function_decl(const_tree expr, ptrset_t &types)
const_tree decl_type = TREE_TYPE(expr);
gcc_assert(decl_type);
// This will collect return, arguments and decl_type itself
- collect_types(decl_type, types);
+ collect_types(decl_type);
}
static void
@@ -295,7 +297,7 @@ collect_types_from_expr(const_tree expr, ptrset_t &types)
gcc_assert(expr);
const_tree type = TREE_TYPE(expr);
gcc_assert(type);
- collect_types(type, types);
+ collect_types(type);
const enum tree_code code = TREE_CODE(expr);
switch (code)
{
@@ -567,7 +569,7 @@ collect_types_from_cnode_locals(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(var_decl);
const_tree var_decl_type = TREE_TYPE(var_decl);
- collect_types(var_decl_type, types);
+ collect_types(var_decl_type);
}
}
@@ -586,7 +588,7 @@ collect_types_from_cnode_ssa_names(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(ssa_name);
const_tree ssa_name_type = TREE_TYPE(ssa_name);
- collect_types(ssa_name_type, types);
+ collect_types(ssa_name_type);
}
pop_cfun();
}
@@ -799,6 +801,14 @@ collect_types(ptrset_t &types)
sanity_check_ptr_xor_complement(types);
}
+static TypeCollector typeCollector;
+ptrset_t *TypeCollector::ptrset = NULL;
+
+static void
+collect_types(const_tree t)
+{
+ typeCollector.collect(t);
+}
static unsigned int
iphw_execute()
@@ -806,6 +816,7 @@ iphw_execute()
//test_type_equality::run_tests();
//test_naming_types::run_tests();
ptrset_t types;
+ TypeCollector::ptrset = &types;
collect_types(types);
filter_out_types_in_set(types);
compare_types_in_set(types);
diff --git a/gcc/name-types.c b/gcc/name-types.c
index 23c6a120456..fe8f6c5575b 100644
--- a/gcc/name-types.c
+++ b/gcc/name-types.c
@@ -33,6 +33,7 @@
#include <string>
#include "name-types.h"
+#include "type-walker.hpp"
// Using std::string because it will manage memory for us
// And we don't know whether the user will free the memory.
diff --git a/gcc/name-types.h b/gcc/name-types.h
index 538956fdd5d..b127bef17ac 100644
--- a/gcc/name-types.h
+++ b/gcc/name-types.h
@@ -5,7 +5,3 @@
const std::string type_to_string(const_tree type, const unsigned field_offset=0, const bool add_prelude=true);
const std::string get_type_identifier(const_tree type);
-
-namespace test_naming_types {
-void run_tests();
-};
diff --git a/gcc/type-collector.c b/gcc/type-collector.c
new file mode 100644
index 00000000000..af8778b8554
--- /dev/null
+++ b/gcc/type-collector.c
@@ -0,0 +1,237 @@
+#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-collector.hpp"
+
+void
+TypeCollector::collect(const_tree t)
+{
+ const bool in_set = ptrset->in_universe(t);
+ // memoization...
+ if (in_set) return;
+ this->_points_to_record = false;
+ gcc_assert(ptrset && t);
+ gcc_assert(ptr.size() == 0);
+ walk(t);
+}
+
+bool
+TypeCollector::is_memoized(const_tree t)
+{
+ const bool in_set = ptrset->in_universe(t);
+ if (!in_set) return false;
+
+ const bool points_to_record = ptrset->in_points_to_record(t);
+ for (auto i = ptr.begin(), e = ptr.end(); i != e; ++i)
+ {
+ i->second = true;
+ }
+ return true;
+}
+
+void
+TypeCollector::_walk_void_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_void_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_integer_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_integer_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_real_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_real_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_fixed_point_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_fixed_point_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_complex_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_complex_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_enumeral_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_enumeral_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_boolean_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_boolean_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_collect_simple(const_tree t)
+{
+ ptrset->insert(t, ptr[t]);
+ ptr.erase(t);
+}
+
+void
+TypeCollector::_walk_array_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_array_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_pointer_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_pointer_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_reference_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_reference_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_record_post(const_tree t)
+{
+ // All in ptr point to record
+ for (auto i = ptr.begin(), e = ptr.end(); i != e; ++i)
+ {
+ i->second = true;
+ }
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_record_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_union_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_union_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_function_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_function_pre(const_tree t)
+{
+ ptr[t] = false;
+}
+
+void
+TypeCollector::_walk_method_post(const_tree t)
+{
+ _collect_simple(t);
+}
+
+void
+TypeCollector::_walk_method_pre(const_tree t)
+{
+ ptr[t] = false;
+}
diff --git a/gcc/type-collector.hpp b/gcc/type-collector.hpp
new file mode 100644
index 00000000000..425b54c5062
--- /dev/null
+++ b/gcc/type-collector.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "type-walker.hpp"
+#include "collect-types.h"
+#include <map>
+
+class TypeCollector : public TypeWalker {
+public:
+ static ptrset_t* ptrset;
+private:
+ bool _points_to_record;
+ std::map<const_tree, bool> ptr;
+
+ void _collect_simple(const_tree t);
+ virtual bool is_memoized(const_tree t);
+
+ virtual void _walk_void_pre(const_tree t);
+ virtual void _walk_void_post(const_tree t);
+ virtual void _walk_integer_pre(const_tree t);
+ virtual void _walk_integer_post(const_tree t);
+ virtual void _walk_real_pre(const_tree t);
+ virtual void _walk_real_post(const_tree t);
+ virtual void _walk_fixed_point_pre(const_tree t);
+ virtual void _walk_fixed_point_post(const_tree t);
+ virtual void _walk_complex_pre(const_tree t);
+ virtual void _walk_complex_post(const_tree t);
+ virtual void _walk_enumeral_pre(const_tree t);
+ virtual void _walk_enumeral_post(const_tree t);
+ virtual void _walk_boolean_pre(const_tree t);
+ virtual void _walk_boolean_post(const_tree t);
+ virtual void _walk_array_pre(const_tree t);
+ virtual void _walk_array_post(const_tree t);
+ virtual void _walk_pointer_pre(const_tree t);
+ virtual void _walk_pointer_post(const_tree t);
+ virtual void _walk_reference_pre(const_tree t);
+ virtual void _walk_reference_post(const_tree t);
+ virtual void _walk_record_pre(const_tree t);
+ virtual void _walk_record_post(const_tree t);
+ virtual void _walk_union_pre(const_tree t);
+ virtual void _walk_union_post(const_tree t);
+ virtual void _walk_function_pre(const_tree t);
+ virtual void _walk_function_post(const_tree t);
+ virtual void _walk_method_pre(const_tree t);
+ virtual void _walk_method_post(const_tree t);
+public:
+ void collect(const_tree t);
+ TypeCollector() : _points_to_record(false) {};
+};
+
diff --git a/gcc/type-stringifier.hpp b/gcc/type-stringifier.hpp
index 33f5cb359cb..98e0546b8d7 100644
--- a/gcc/type-stringifier.hpp
+++ b/gcc/type-stringifier.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "type-walker.hpp"
+#include <string>
class TypeStringifier : public TypeWalker
{
@@ -8,10 +9,11 @@ private:
std::string _stringification;
static std::string get_type_identifier(const_tree t);
+ static std::string get_field_identifier(const_tree t);
- void _stringifiy_simple(const_tree t);
- void _stringifiy_aggregate_pre(const_tree t);
- void _stringifiy_aggregate_post(const_tree t);
+ void _stringify_simple(const_tree t);
+ void _stringify_aggregate_pre(const_tree t);
+ void _stringify_aggregate_post(const_tree t);
void _stringify_fm_pre(const_tree t);
void _stringify_fm_post(const_tree t);
@@ -29,109 +31,119 @@ private:
virtual void _walk_record_post(const_tree t);
virtual void _walk_union_pre(const_tree t);
virtual void _walk_union_post(const_tree t);
+ virtual void _walk_field_post(const_tree t);
+ virtual void _walk_return_pre(const_tree t);
+ virtual void _walk_return_post(const_tree t);
+ virtual void _walk_args_pre(const_tree t);
+ virtual void _walk_args_post(const_tree t);
+ virtual void _walk_arg_post(const_tree t);
virtual void _walk_method_pre(const_tree t);
virtual void _walk_method_post(const_tree t);
virtual void _walk_function_pre(const_tree t);
virtual void _walk_function_post(const_tree t);
public:
- std::string stringifiy(const_tree t);
+ std::string stringify(const_tree t);
TypeStringifier() {};
};
std::string
TypeStringifier::stringify(const_tree t)
{
+ _stringification.clear();
gcc_assert(t);
walk(t);
+ return _stringification;
}
-virtual void
+void
TypeStringifier::_walk_void_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_integer_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_real_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_fixed_point_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_complex_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_offset_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
-virtual void
+void
TypeStringifier::_walk_boolean_pre(const_tree t)
{
- _stringifiy_simple(t);
+ _stringify_simple(t);
}
void
-TypeStringifier::_stringifiy_simple(const_tree t)
+TypeStringifier::_stringify_simple(const_tree t)
{
gcc_assert(t);
const enum tree_code code = TREE_CODE(t);
this->_stringification += std::string(get_tree_code_name(code));
}
-virtual void
+void
TypeStringifier::_walk_pointer_post(const_tree t)
{
this->_stringification += std::string("*");
}
-virtual void
+void
TypeStringifier::_walk_array_post(const_tree t)
{
this->_stringification += std::string("[]");
}
-virtual void
+void
TypeStringifier::_walk_reference_post(const_tree t)
{
this->_stringification += std::string("&");
}
-virtual void
+void
TypeStringifier::_walk_union_pre(const_tree t)
{
+ this->_stringification += std::string(" union ");
_stringify_aggregate_pre(t);
}
-virtual void
+void
TypeStringifier::_walk_union_post(const_tree t)
{
_stringify_aggregate_post(t);
}
-virtual void
+void
TypeStringifier::_walk_record_pre(const_tree t)
{
+ this->_stringification += std::string(" record ");
_stringify_aggregate_pre(t);
}
-virtual void
+void
TypeStringifier::_walk_record_post(const_tree t)
{
_stringify_aggregate_post(t);
@@ -150,6 +162,12 @@ TypeStringifier::_stringify_aggregate_post(const_tree t)
}
void
+TypeStringifier::_walk_field_post(const_tree t)
+{
+ this->_stringification += std::string(" ") + TypeStringifier::get_field_identifier(t) + std::string(";");
+}
+
+void
TypeStringifier::_walk_method_pre(const_tree t)
{
_stringify_fm_pre(t);
@@ -176,7 +194,6 @@ TypeStringifier::_walk_function_post(const_tree t)
void
TypeStringifier::_stringify_fm_pre(const_tree t)
{
-
this->_stringification += std::string("function { ");
}
@@ -186,7 +203,37 @@ TypeStringifier::_stringify_fm_post(const_tree t)
this->_stringification += std::string("}");
}
-static std::string
+void
+TypeStringifier::_walk_return_pre(const_tree t)
+{
+ this->_stringification += std::string("(");
+}
+
+void
+TypeStringifier::_walk_return_post(const_tree t)
+{
+ this->_stringification += std::string(")");
+}
+
+void
+TypeStringifier::_walk_args_pre(const_tree t)
+{
+ this->_stringification += std::string("(");
+}
+
+void
+TypeStringifier::_walk_args_post(const_tree t)
+{
+ this->_stringification += std::string(")");
+}
+
+void
+TypeStringifier::_walk_arg_post(const_tree t)
+{
+ this->_stringification += std::string(", ");
+}
+
+std::string
TypeStringifier::get_type_identifier(const_tree t)
{
tree name = TYPE_NAME(t);
@@ -201,3 +248,13 @@ TypeStringifier::get_type_identifier(const_tree t)
return std::string(identifier_ptr);
}
+std::string
+TypeStringifier::get_field_identifier(const_tree t)
+{
+ assert_is_type(t, FIELD_DECL);
+ const_tree decl_name = DECL_NAME(t);
+ if (!decl_name) return std::string("");
+
+ const char* identifier = IDENTIFIER_POINTER(decl_name);
+ return std::string(identifier);
+}
diff --git a/gcc/type-walker.c b/gcc/type-walker.c
new file mode 100644
index 00000000000..df672d8bdf0
--- /dev/null
+++ b/gcc/type-walker.c
@@ -0,0 +1,402 @@
+#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);
+}
diff --git a/gcc/type-walker.hpp b/gcc/type-walker.hpp
index df09fcdb2b0..0f775d170e8 100644
--- a/gcc/type-walker.hpp
+++ b/gcc/type-walker.hpp
@@ -1,17 +1,18 @@
#pragma once
-#include "types-inlines.h"
#include <set>
class TypeWalker {
-private:
+protected:
typedef std::set<const_tree> tset_t;
+private:
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 bool is_memoized(const_tree t) { return false; };
virtual void _walk_void_pre(const_tree t) {};
void walk_void(const_tree t, tset_t &tset);
@@ -30,7 +31,7 @@ private:
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);
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) {};
@@ -65,6 +66,22 @@ private:
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_field_pre(const_tree) {};
+ void walk_field(const_tree t, tset_t &tset);
+ void _walk_field(const_tree t, tset_t &tset);
+ virtual void _walk_field_post(const_tree t) {};
+ virtual void _walk_return_pre(const_tree t) {};
+ void walk_return(const_tree, tset_t &tset);
+ void _walk_return(const_tree, tset_t &tset);
+ virtual void _walk_return_post(const_tree t) {};
+ virtual void _walk_args_pre(const_tree t) {};
+ void walk_args(const_tree t, tset_t &tset);
+ void _walk_args(const_tree t, tset_t &tset);
+ virtual void _walk_args_post(const_tree t) {};
+ virtual void _walk_arg_pre(const_tree t) {};
+ void walk_arg(const_tree t, tset_t &tset);
+ void _walk_arg(const_tree t, tset_t &tset);
+ virtual void _walk_arg_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);
@@ -78,313 +95,3 @@ public:
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);
- }
-}