summaryrefslogtreecommitdiff
path: root/gcc/type-reconstructor.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/type-reconstructor.c')
-rw-r--r--gcc/type-reconstructor.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/gcc/type-reconstructor.c b/gcc/type-reconstructor.c
index 530569c074f..350d9bd4989 100644
--- a/gcc/type-reconstructor.c
+++ b/gcc/type-reconstructor.c
@@ -49,7 +49,6 @@ get_new_identifier(const_tree type)
gcc_assert(!is_new_type);
char *new_name;
asprintf(&new_name, "%s.reorg", identifier);
- log("old %s new %s\n", identifier, new_name);
return get_identifier(new_name);
}
@@ -58,6 +57,8 @@ get_new_identifier(const_tree type)
//
// Invariant for all _post functions:
// _reorg_map[TREE_TYPE(t)] != NULL
+// unless TREE_TYPE(t) is not a type which points to a record
+// a.k.a. no modifications
//
// To preserve invariant, we must include
// the following at the end of all _post functions:
@@ -80,16 +81,17 @@ TypeReconstructor::_walk_ARRAY_TYPE_post(const_tree t)
{
const_tree inner_type = TREE_TYPE(t);
gcc_assert(inner_type);
- tree inner_reorg_type = (tree)_reorg_map[inner_type];
- gcc_assert(inner_reorg_type);
- tree t_reorg = (tree)_working_stack.top();
+ const bool in_map = _reorg_map.find(inner_type) != _reorg_map.end();
+ tree t_reorg = _working_stack.top();
_working_stack.pop();
+ if (!in_map) return;
+
+ tree inner_reorg_type = _reorg_map[inner_type];
TREE_TYPE(t_reorg) = inner_reorg_type;
TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg);
_reorg_map[t] = t_reorg;
-
-
+ log("working type %s\n", t_reorg ? "t" : "f");
}
void
@@ -103,23 +105,19 @@ TypeReconstructor::_walk_POINTER_TYPE_pre(const_tree t)
void
TypeReconstructor::_walk_POINTER_TYPE_post(const_tree t)
{
- const bool already_changed = _reorg_map.find(t) != _reorg_map.end();
- const_tree modifications = _working_stack.top();
+ tree t_reorg = _working_stack.top();
_working_stack.pop();
- if (already_changed) return;
- tree tt = TREE_TYPE(t);
- bool field_type_in_reorg_map = _reorg_map.find(tt) != _reorg_map.end();
- if (!field_type_in_reorg_map) {
- TYPE_NAME((tree)modifications) = get_new_identifier(modifications);
- _reorg_map[t] = modifications;
- return;
- }
+ const_tree inner_type = TREE_TYPE(t);
+ const bool in_map = _reorg_map.find(inner_type) != _reorg_map.end();
+ // We are pointing to an integer or something like that.
+ if (!in_map) return;
- tree tf = (tree)_reorg_map[tt];
- TREE_TYPE((tree)modifications) = tf;
- TYPE_NAME((tree)modifications) = get_new_identifier(modifications);
- _reorg_map[t] = modifications;
+ tree inner_type_reorg = _reorg_map[inner_type];
+ TREE_TYPE((tree)t_reorg) = inner_type_reorg;
+ TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg);
+ _reorg_map[t] = t_reorg;;
+ log("working type %s\n", t_reorg ? "t" : "f");
}
void
@@ -143,6 +141,34 @@ TypeReconstructor::_walk_RECORD_TYPE_pre(const_tree t)
_eliminated_fields.push(vec2);
}
+void
+TypeReconstructor::_walk_UNION_TYPE_pre(const_tree t)
+{
+ const bool in_map = _records.find(t) != _records.end();
+ // The modifying stack let's us know if the current record
+ // type is being modified.
+ gcc_assert(!in_map);
+ _modifying.push(in_map);
+
+ field_offsets_t empty;
+ _record_stack.push(in_map ? _records[t] : empty);
+
+ // We really should only make a distinct type copy if
+ // it points to a pointer that will be rewritten...
+ _working_stack.push(build_distinct_type_copy((tree)t));
+
+ type_vector_t vec;
+ type_vector_t vec2;
+ _field_decls.push(vec);
+ _eliminated_fields.push(vec2);
+}
+
+void
+TypeReconstructor::_walk_UNION_TYPE_post(const_tree t)
+{
+ _walk_RECORD_TYPE_post(t);
+}
+
void
TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
@@ -156,7 +182,7 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
type_vector_t fields_to_eliminate = _eliminated_fields.top();
_eliminated_fields.pop();
_field_decls.pop();
- const_tree working_type = _working_stack.top();
+ tree working_type = _working_stack.top();
_working_stack.pop();
_record_stack.pop();
const bool should_be_modified = _modifying.top();
@@ -175,8 +201,8 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
if (fields_to_keep.empty())
{
- layout_type((tree)working_type);
- TYPE_NAME((tree)working_type) = get_new_identifier(working_type);
+ layout_type(working_type);
+ TYPE_NAME(working_type) = get_new_identifier(working_type);
_reorg_map[t] = working_type;
return;
}
@@ -186,7 +212,7 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
bool field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end();
if (field_type_in_reorg_map)
{
- TREE_TYPE(f) = (tree) _reorg_map[tf];
+ TREE_TYPE(f) = _reorg_map[tf];
}
TYPE_FIELDS((tree)working_type) = f;
unsigned s = fields_to_keep.size();
@@ -198,14 +224,15 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end();
if (field_type_in_reorg_map)
{
- TREE_TYPE(current) = (tree) _reorg_map[tf];
+ TREE_TYPE(current) = _reorg_map[tf];
}
DECL_CHAIN(f) = current;
f = current;
}
- layout_type((tree)working_type);
- TYPE_NAME((tree)working_type) = get_new_identifier(working_type);
+ layout_type(working_type);
+ TYPE_NAME(working_type) = get_new_identifier(working_type);
+ log("working type %s\n", working_type ? "t" : "f");
_reorg_map[t] = working_type;
}