Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
46fbaaf3
Commit
46fbaaf3
authored
Jul 18, 2002
by
Götz Lindenmaier
Browse files
implemented typecheck, called in inline_method.
[r445]
parent
167eae6f
Changes
8
Hide whitespace changes
Inline
Side-by-side
ir/common/bool.h
View file @
46fbaaf3
...
...
@@ -23,4 +23,9 @@ typedef unsigned char bool;
# define FALSE 0
# endif
/* ndef TRUE */
# ifndef true
# define true 1
# define false 0
# endif
/* ndef TRUE */
# endif
/* _BOOL_H_ */
ir/ir/irgopt.c
View file @
46fbaaf3
...
...
@@ -432,6 +432,8 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
/** Check preconditions **/
assert
(
get_irn_op
(
call
)
==
op_Call
);
/* assert(get_Call_type(call) == get_entity_type(get_irg_ent(called_graph))); */
assert
(
smaller_type
(
get_entity_type
(
get_irg_ent
(
called_graph
)),
get_Call_type
(
call
)));
assert
(
get_type_tpop
(
get_Call_type
(
call
))
==
type_method
);
if
(
called_graph
==
current_ir_graph
)
return
;
...
...
ir/ir/irmode.c
View file @
46fbaaf3
...
...
@@ -508,3 +508,14 @@ mode_is_dataM (ir_mode *mode)
}
return
res
;
}
/* Returns true if sm can be converted to lm without loss. */
bool
smaller_mode
(
ir_mode
*
sm
,
ir_mode
*
lm
)
{
if
((
mode_is_int
(
sm
)
&&
mode_is_int
(
lm
))
&&
get_mode_modecode
(
sm
)
<=
get_mode_modecode
(
lm
))
return
true
;
if
((
mode_is_float
(
sm
)
&&
mode_is_float
(
lm
))
&&
get_mode_modecode
(
sm
)
<=
get_mode_modecode
(
lm
))
return
true
;
}
ir/ir/irmode.h
View file @
46fbaaf3
...
...
@@ -20,6 +20,7 @@ reimplementation of the tarval module.
# define _IRMODE_H_
#include "ident.h"
#include "bool.h"
# define target_bits 8
...
...
@@ -128,4 +129,8 @@ int mode_is_data (ir_mode *mode);
int
mode_is_datab
(
ir_mode
*
mode
);
int
mode_is_dataM
(
ir_mode
*
mode
);
/* Returns true if sm can be converted to lm without loss
according to firm definiton */
bool
smaller_mode
(
ir_mode
*
sm
,
ir_mode
*
lm
);
# endif
/* _IRMODE_H_ */
ir/tr/entity.c
View file @
46fbaaf3
...
...
@@ -506,3 +506,7 @@ int is_compound_entity(entity *ent) {
return
(
is_class_type
(
t
)
||
is_struct_type
(
t
)
||
is_array_type
(
t
)
||
is_union_type
(
t
));
}
bool
equal_entity
(
entity
*
ent1
,
entity
*
ent2
)
{
return
true
;
}
ir/tr/entity.h
View file @
46fbaaf3
...
...
@@ -277,6 +277,11 @@ int is_atomic_entity(entity *ent);
array or union type. */
int
is_compound_entity
(
entity
*
ent
);
/* Returns true if ent1 and ent2 have are equal except for their owner.
Two entities are equal if
- they have the same type (the same C-struct)
*/
bool
equal_entity
(
entity
*
ent1
,
entity
*
ent2
);
/*****/
...
...
ir/tr/type.c
View file @
46fbaaf3
...
...
@@ -255,6 +255,251 @@ int is_type (void *thing) {
return
0
;
}
bool
equal_type
(
type
*
typ1
,
type
*
typ2
)
{
entity
**
m
;
type
**
t
;
int
i
,
j
;
if
(
typ1
==
typ2
)
return
true
;
if
((
get_type_tpop_code
(
typ1
)
!=
get_type_tpop_code
(
typ2
))
||
(
get_type_name
(
typ1
)
!=
get_type_name
(
typ2
))
||
(
get_type_mode
(
typ1
)
!=
get_type_mode
(
typ2
))
||
(
get_type_state
(
typ1
)
!=
get_type_state
(
typ2
)))
return
false
;
if
((
get_type_state
(
typ1
)
==
layout_fixed
)
&&
(
get_type_size
(
typ1
)
!=
get_type_size
(
typ2
)))
return
false
;
switch
(
get_type_tpop_code
(
typ1
))
{
case
tpo_class
:
{
if
(
get_class_n_members
(
typ1
)
!=
get_class_n_members
(
typ2
))
return
false
;
if
(
get_class_n_subtypes
(
typ1
)
!=
get_class_n_subtypes
(
typ2
))
return
false
;
if
(
get_class_n_supertypes
(
typ1
)
!=
get_class_n_supertypes
(
typ2
))
return
false
;
if
(
get_class_peculiarity
(
typ1
)
!=
get_class_peculiarity
(
typ2
))
return
false
;
/** Compare the members **/
m
=
alloca
(
sizeof
(
entity
*
)
*
get_class_n_members
(
typ1
));
memset
(
m
,
0
,
sizeof
(
entity
*
)
*
get_class_n_members
(
typ1
));
/* First sort the members of typ2 */
for
(
i
=
0
;
i
<
get_class_n_members
(
typ1
);
i
++
)
{
entity
*
e1
=
get_class_member
(
typ1
,
i
);
for
(
j
=
0
;
j
<
get_class_n_members
(
typ2
);
j
++
)
{
entity
*
e2
=
get_class_member
(
typ2
,
j
);
if
(
get_entity_name
(
e1
)
==
get_entity_name
(
e2
))
m
[
i
]
=
e2
;
}
}
for
(
i
=
0
;
i
<
get_class_n_members
(
typ1
);
i
++
)
{
if
(
!
m
[
i
]
||
/* Found no counterpart */
!
equal_entity
(
get_class_member
(
typ1
,
i
),
m
[
i
]))
return
false
;
}
/** Compare the supertypes **/
t
=
alloca
(
sizeof
(
entity
*
)
*
get_class_n_supertypes
(
typ1
));
memset
(
t
,
0
,
sizeof
(
entity
*
)
*
get_class_n_supertypes
(
typ1
));
/* First sort the supertypes of typ2 */
for
(
i
=
0
;
i
<
get_class_n_supertypes
(
typ1
);
i
++
)
{
type
*
t1
=
get_class_supertype
(
typ1
,
i
);
for
(
j
=
0
;
j
<
get_class_n_supertypes
(
typ2
);
j
++
)
{
type
*
t2
=
get_class_supertype
(
typ2
,
j
);
if
(
get_type_name
(
t2
)
==
get_type_name
(
t1
))
t
[
i
]
=
t2
;
}
}
for
(
i
=
0
;
i
<
get_class_n_supertypes
(
typ1
);
i
++
)
{
if
(
!
t
[
i
]
||
/* Found no counterpart */
get_class_supertype
(
typ1
,
i
)
!=
t
[
i
])
return
false
;
}
}
break
;
case
tpo_struct
:
{
if
(
get_struct_n_members
(
typ1
)
!=
get_struct_n_members
(
typ2
))
return
false
;
m
=
alloca
(
sizeof
(
entity
*
)
*
get_struct_n_members
(
typ1
));
memset
(
m
,
0
,
sizeof
(
entity
*
)
*
get_struct_n_members
(
typ1
));
/* First sort the members of lt */
for
(
i
=
0
;
i
<
get_struct_n_members
(
typ1
);
i
++
)
{
entity
*
e1
=
get_struct_member
(
typ1
,
i
);
for
(
j
=
0
;
j
<
get_struct_n_members
(
typ2
);
j
++
)
{
entity
*
e2
=
get_struct_member
(
typ2
,
j
);
if
(
get_entity_name
(
e1
)
==
get_entity_name
(
e2
))
m
[
i
]
=
e2
;
}
}
for
(
i
=
0
;
i
<
get_struct_n_members
(
typ1
);
i
++
)
{
if
(
!
m
[
i
]
||
/* Found no counterpart */
!
equal_entity
(
get_struct_member
(
typ1
,
i
),
m
[
i
]))
return
false
;
}
}
break
;
case
tpo_method
:
{
if
(
get_method_n_params
(
typ1
)
!=
get_method_n_params
(
typ2
))
return
false
;
if
(
get_method_n_ress
(
typ1
)
!=
get_method_n_ress
(
typ2
))
return
false
;
for
(
i
=
0
;
i
<
get_method_n_params
(
typ1
);
i
++
)
{
if
(
!
equal_type
(
get_method_param_type
(
typ1
,
i
),
get_method_param_type
(
typ2
,
i
)))
return
false
;
}
for
(
i
=
0
;
i
<
get_method_n_ress
(
typ1
);
i
++
)
{
if
(
!
equal_type
(
get_method_res_type
(
typ1
,
i
),
get_method_res_type
(
typ2
,
i
)))
return
false
;
}
}
break
;
case
tpo_union
:
{
if
(
get_union_n_members
(
typ1
)
!=
get_union_n_members
(
typ2
))
return
false
;
m
=
alloca
(
sizeof
(
entity
*
)
*
get_union_n_members
(
typ1
));
memset
(
m
,
0
,
sizeof
(
entity
*
)
*
get_union_n_members
(
typ1
));
/* First sort the members of lt */
for
(
i
=
0
;
i
<
get_union_n_members
(
typ1
);
i
++
)
{
entity
*
e1
=
get_union_member
(
typ1
,
i
);
for
(
j
=
0
;
j
<
get_union_n_members
(
typ2
);
j
++
)
{
entity
*
e2
=
get_union_member
(
typ2
,
j
);
if
(
get_entity_name
(
e1
)
==
get_entity_name
(
e2
))
m
[
i
]
=
e2
;
}
}
for
(
i
=
0
;
i
<
get_union_n_members
(
typ1
);
i
++
)
{
if
(
!
m
[
i
]
||
/* Found no counterpart */
!
equal_entity
(
get_union_member
(
typ1
,
i
),
m
[
i
]))
return
false
;
}
}
break
;
case
tpo_array
:
{
type
*
set
,
*
let
;
/* small/large elt. type */
if
(
get_array_n_dimensions
(
typ1
)
!=
get_array_n_dimensions
(
typ2
))
return
false
;
if
(
!
equal_type
(
get_array_element_type
(
typ1
),
get_array_element_type
(
typ2
)))
return
false
;
for
(
i
=
0
;
i
<
get_array_n_dimensions
(
typ1
);
i
++
)
{
if
(
get_array_lower_bound
(
typ1
,
i
)
!=
get_array_lower_bound
(
typ2
,
i
)
||
get_array_upper_bound
(
typ1
,
i
)
!=
get_array_upper_bound
(
typ2
,
i
))
return
false
;
if
(
get_array_order
(
typ1
,
i
)
!=
get_array_order
(
typ2
,
i
))
assert
(
0
&&
"type compare with different dimension orders not implemented"
);
}
}
break
;
case
tpo_enumeration
:
{
assert
(
0
&&
"enumerations not implemented"
);
}
break
;
case
tpo_pointer
:
{
if
(
get_pointer_points_to_type
(
typ1
)
!=
get_pointer_points_to_type
(
typ2
))
return
false
;
}
break
;
case
tpo_primitive
:
{
}
break
;
default:
break
;
}
return
true
;
}
bool
smaller_type
(
type
*
st
,
type
*
lt
)
{
entity
**
m
;
int
i
,
j
;
if
(
st
==
lt
)
return
true
;
if
(
get_type_tpop_code
(
st
)
!=
get_type_tpop_code
(
lt
))
return
false
;
switch
(
get_type_tpop_code
(
st
))
{
case
tpo_class
:
{
return
is_subclass_of
(
st
,
lt
);
}
break
;
case
tpo_struct
:
{
if
(
get_struct_n_members
(
st
)
!=
get_struct_n_members
(
lt
))
return
false
;
m
=
alloca
(
sizeof
(
entity
*
)
*
get_struct_n_members
(
st
));
memset
(
m
,
0
,
sizeof
(
entity
*
)
*
get_struct_n_members
(
st
));
/* First sort the members of lt */
for
(
i
=
0
;
i
<
get_struct_n_members
(
st
);
i
++
)
{
entity
*
se
=
get_struct_member
(
st
,
i
);
for
(
j
=
0
;
j
<
get_struct_n_members
(
lt
);
j
++
)
{
entity
*
le
=
get_struct_member
(
lt
,
j
);
if
(
get_entity_name
(
le
)
==
get_entity_name
(
se
))
m
[
i
]
=
le
;
}
}
for
(
i
=
0
;
i
<
get_struct_n_members
(
st
);
i
++
)
{
if
(
!
m
[
i
]
||
/* Found no counterpart */
!
smaller_type
(
get_entity_type
(
get_struct_member
(
st
,
i
)),
get_entity_type
(
m
[
i
])))
return
false
;
}
}
break
;
case
tpo_method
:
{
if
(
get_method_n_params
(
st
)
!=
get_method_n_params
(
lt
))
return
false
;
if
(
get_method_n_ress
(
st
)
!=
get_method_n_ress
(
lt
))
return
false
;
for
(
i
=
0
;
i
<
get_method_n_params
(
st
);
i
++
)
{
if
(
!
smaller_type
(
get_method_param_type
(
st
,
i
),
get_method_param_type
(
lt
,
i
)))
return
false
;
}
for
(
i
=
0
;
i
<
get_method_n_ress
(
st
);
i
++
)
{
if
(
!
smaller_type
(
get_method_res_type
(
st
,
i
),
get_method_res_type
(
lt
,
i
)))
return
false
;
}
}
break
;
case
tpo_union
:
{
if
(
get_union_n_members
(
st
)
!=
get_union_n_members
(
lt
))
return
false
;
m
=
alloca
(
sizeof
(
entity
*
)
*
get_union_n_members
(
st
));
memset
(
m
,
0
,
sizeof
(
entity
*
)
*
get_union_n_members
(
st
));
/* First sort the members of lt */
for
(
i
=
0
;
i
<
get_union_n_members
(
st
);
i
++
)
{
entity
*
se
=
get_union_member
(
st
,
i
);
for
(
j
=
0
;
j
<
get_union_n_members
(
lt
);
j
++
)
{
entity
*
le
=
get_union_member
(
lt
,
j
);
if
(
get_entity_name
(
le
)
==
get_entity_name
(
se
))
m
[
i
]
=
le
;
}
}
for
(
i
=
0
;
i
<
get_union_n_members
(
st
);
i
++
)
{
if
(
!
m
[
i
]
||
/* Found no counterpart */
!
smaller_type
(
get_entity_type
(
get_union_member
(
st
,
i
)),
get_entity_type
(
m
[
i
])))
return
false
;
}
}
break
;
case
tpo_array
:
{
type
*
set
,
*
let
;
/* small/large elt. type */
if
(
get_array_n_dimensions
(
st
)
!=
get_array_n_dimensions
(
lt
))
return
false
;
set
=
get_array_element_type
(
st
);
let
=
get_array_element_type
(
lt
);
if
(
set
!=
let
)
{
/* If the elt types are different, set must be convertible
to let, and they must have the same size so that address
computations work out. To have a size the layout must
be fixed. */
if
((
get_type_state
(
set
)
!=
layout_fixed
)
||
(
get_type_state
(
let
)
!=
layout_fixed
))
return
false
;
if
(
!
smaller_type
(
set
,
let
)
||
get_type_size
(
set
)
!=
get_type_size
(
let
))
return
false
;
}
for
(
i
=
0
;
i
<
get_array_n_dimensions
(
st
);
i
++
)
{
if
(
get_array_lower_bound
(
lt
,
i
))
if
(
get_array_lower_bound
(
st
,
i
)
!=
get_array_lower_bound
(
lt
,
i
))
return
false
;
if
(
get_array_upper_bound
(
lt
,
i
))
if
(
get_array_upper_bound
(
st
,
i
)
!=
get_array_upper_bound
(
lt
,
i
))
return
false
;
}
}
break
;
case
tpo_enumeration
:
{
assert
(
0
&&
"enumerations not implemented"
);
}
break
;
case
tpo_pointer
:
{
if
(
!
smaller_type
(
get_pointer_points_to_type
(
st
),
get_pointer_points_to_type
(
lt
)))
return
false
;
}
break
;
case
tpo_primitive
:
{
if
(
!
smaller_mode
(
get_type_mode
(
st
),
get_type_mode
(
lt
)))
return
false
;
}
break
;
default:
break
;
}
return
true
;
}
/*******************************************************************/
/** TYPE_CLASS **/
/*******************************************************************/
...
...
@@ -420,6 +665,20 @@ bool is_class_type(type *clss) {
if
(
clss
->
type_op
==
type_class
)
return
1
;
else
return
0
;
}
bool
is_subclass_of
(
type
*
low
,
type
*
high
)
{
int
i
;
assert
(
is_class_type
(
low
)
&&
is_class_type
(
high
));
if
(
low
==
high
)
return
true
;
/* depth first search from high downwards. */
for
(
i
=
0
;
i
<
get_class_n_subtypes
(
high
);
i
++
)
{
if
(
low
==
get_class_subtype
(
high
,
i
))
return
true
;
if
(
is_subclass_of
(
low
,
get_class_subtype
(
high
,
i
)))
return
true
;
}
return
false
;
}
/*******************************************************************/
/** TYPE_STRUCT **/
/*******************************************************************/
...
...
ir/tr/type.h
View file @
46fbaaf3
...
...
@@ -189,6 +189,86 @@ extern unsigned long type_visited;
*/
int
is_type
(
void
*
thing
);
/****f* type/equal_types
*
* NAME
* equal_type - Checks whether two types are structural equal.
* SYNOPSIS
* bool equal_types (type *typ1, type *typ2);
* INPUTS
* two pointer types
* RESULT
* true if the types are equal, else false.
* Types are equal if
* - they are the same type kind
* - they have the same name
* - they have the same mode (if applicable)
* - they have the same type_state and, ev., the same size
* - they are class types and have
* - the same members (see same_entity in entity.h)
* - the same supertypes -- the C-pointers are compared --> no recursive call.
* - the same number of subtypes. Subtypes are not compared,
* as this could cause a cyclic test.
* - the same peculiarity
* - they are structure types and have the same members
* - they are method types and have
* - the same parameter types
* - the same result types
* - they are union types and have the same members
* - they are array types and have
* - the same number of dimensions
* - the same dimension bounds
* - the same dimension order
* - the same element type
* - they are enumeration types and have the same enumerator names
* - they are pointer types and have the identical points_to type
* (i.e., the same C-struct to represent the type, type_id is skipped.
* This is to avoid endless recursions; with pointer types circlic
* type graphs are possible.)
*
***
*/
bool
equal_type
(
type
*
tpy1
,
type
*
typ2
);
/****f* type/smaller_type
*
* NAME
* smaller_type - Checks whether two types are structural comparable.
* SYNOPSIS
* bool smaller_type (type *st, type *lt);
* INPUTS
* two pointer type
* RESULT
* true if type st is smaller than type lt, i.e. whenever
* lt is expected a st can be used.
* This is true if
* - they are the same type kind
* - mode(st) < mode (lt) (if applicable)
* - they are class types and st is (transitive) subtype of lt,
* - they are structure types and
* - the members of st have exactly one counterpart in lt with the same name,
* - the counterpart has a bigger type.
* - they are method types and have
* - the same number of parameter and result types,
* - the parameter types of st are smaller than those of lt,
* - the result types of st are smaller than those of lt
* - they are union types and have the members of st have exactly one
* counterpart in lt and the type is smaller
* - they are array types and have
* - the same number of dimensions
* - all bounds of lt are bound of st
* - the same dimension order
* - the same element type
* or
* - the element type of st is smaller than that of lt
* - the element types have the same size and fixed layout.
* - they are enumeration types and have the same enumerator names
* - they are pointer types and have the points_to type of st is
* smaller than the points_to type of lt.
***
*/
bool
smaller_type
(
type
*
st
,
type
*
lt
);
/****** type/class
* NAME
* Representation of a class type.
...
...
@@ -301,7 +381,9 @@ void set_class_dfn (type*, int);
int
get_class_dfn
(
type
*
);
/* typecheck */
bool
is_class_type
(
type
*
clss
);
bool
is_class_type
(
type
*
clss
);
/* Returns true if low is subclass of high. */
bool
is_subclass_of
(
type
*
low
,
type
*
high
);
/*****/
/****** type/struct
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment