#include <nidl.h>
#include <ast.h>
#include <astp.h>
#include <irep.h>
static void IR_gen_type_rep(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
);
#define IR_INIT_INFO(node_p)\
{\
\
node_p->ir_info = NEW (IR_info_n_t);\
}
#define IR_INIT_NODE(node_p)\
{\
\
node_p->ir_info = NEW (IR_info_n_t);\
\
\
node_p->data_tups = NEW (IR_tup_n_t);\
node_p->data_tups->opcode = IR_op_noop_k;\
node_p->data_tups->flags = 0;\
node_p->data_tups->next = NULL;\
\
\
node_p->ir_info->cur_tup_p = node_p->data_tups;\
}
static IR_tup_n_t *IR_cur_tup_p
(
IR_scope_ctx_t *ctx_p
)
{
IR_type_scope_t *type_s_p;
if (ctx_p->type_scope == 0)
return ctx_p->param_p->ir_info->cur_tup_p;
type_s_p = &(ctx_p->type_s_a[ctx_p->type_scope]);
if (type_s_p->flags & IR_REP_AS)
return type_s_p->type_p->rep_as_type->ir_info->cur_tup_p;
if (type_s_p->flags & IR_CS_CHAR)
return type_s_p->type_p->cs_char_type->ir_info->cur_tup_p;
return type_s_p->type_p->ir_info->cur_tup_p;
}
static void IR_insert_irep_tup
(
IR_tup_n_t *tup_p,
IR_tup_n_t **p_insert_p
)
{
tup_p->next = (*p_insert_p)->next;
(*p_insert_p)->next = tup_p;
*p_insert_p = tup_p;
}
static IR_tup_n_t *IR_gen_irep_tup
(
IR_scope_ctx_t *ctx_p,
IR_opcode_k_t opcode
)
{
IR_tup_n_t *tup_p;
tup_p = NEW (IR_tup_n_t);
tup_p->opcode = opcode;
tup_p->flags = 0;
tup_p->next = NULL;
if (ctx_p->type_scope == 0)
IR_insert_irep_tup(tup_p, &ctx_p->param_p->ir_info->cur_tup_p);
else if (ctx_p->type_s_a[ctx_p->type_scope].flags & IR_REP_AS)
IR_insert_irep_tup(tup_p, &ctx_p->type_s_a[ctx_p->type_scope].type_p->
rep_as_type->ir_info->cur_tup_p);
else if (ctx_p->type_s_a[ctx_p->type_scope].flags & IR_CS_CHAR)
IR_insert_irep_tup(tup_p, &ctx_p->type_s_a[ctx_p->type_scope].type_p->
cs_char_type->ir_info->cur_tup_p);
else
IR_insert_irep_tup(tup_p, &ctx_p->type_s_a[ctx_p->type_scope].type_p->
ir_info->cur_tup_p);
return tup_p;
}
static void IR_free_irep_tup
(
IR_scope_ctx_t *ctx_p,
IR_tup_n_t *tup_p,
IR_tup_n_t *pred_tup_p
)
{
if (pred_tup_p != NULL)
{
if (pred_tup_p->next != tup_p)
INTERNAL_ERROR("Inconsistency in linked list");
pred_tup_p->next = tup_p->next;
if (ctx_p->type_scope == 0)
{
if (ctx_p->param_p->ir_info->cur_tup_p == tup_p)
ctx_p->param_p->ir_info->cur_tup_p = pred_tup_p;
}
else if (ctx_p->type_s_a[ctx_p->type_scope].flags & IR_REP_AS)
{
if (ctx_p->type_s_a[ctx_p->type_scope].type_p->
rep_as_type->ir_info->cur_tup_p == tup_p)
ctx_p->type_s_a[ctx_p->type_scope].type_p->
rep_as_type->ir_info->cur_tup_p = pred_tup_p;
}
else if (ctx_p->type_s_a[ctx_p->type_scope].flags & IR_CS_CHAR)
{
if (ctx_p->type_s_a[ctx_p->type_scope].type_p->
cs_char_type->ir_info->cur_tup_p == tup_p)
ctx_p->type_s_a[ctx_p->type_scope].type_p->
cs_char_type->ir_info->cur_tup_p = pred_tup_p;
}
else
{
if (ctx_p->type_s_a[ctx_p->type_scope].type_p->
ir_info->cur_tup_p == tup_p)
ctx_p->type_s_a[ctx_p->type_scope].type_p->
ir_info->cur_tup_p = pred_tup_p;
}
}
FREE(tup_p);
}
static IR_tup_n_t *IR_gen_alignment
(
IR_scope_ctx_t *ctx_p,
int alignment
)
{
IR_tup_n_t *tup_p;
if (alignment <= 1)
tup_p = NULL;
else
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_align_k);
tup_p->arg[IR_ARG_INT].int_val = alignment;
}
return tup_p;
}
static unsigned long IR_param_num
(
AST_parameter_n_t *lookup_p
)
{
AST_operation_n_t *oper_p;
AST_parameter_n_t *param_p;
unsigned long param_num;
oper_p = lookup_p->uplink;
param_num = 0;
for (param_p = oper_p->parameters; param_p != NULL; param_p = param_p->next)
{
param_num++;
if (param_p == lookup_p)
return param_num;
}
if (param_p == oper_p->result)
return 0;
INTERNAL_ERROR("Parameter not found in operation parameter list");
return 0;
}
static unsigned long IR_field_num
(
IR_scope_ctx_t *ctx_p ATTRIBUTE_UNUSED,
AST_field_n_t *attr_field_p,
AST_field_n_t *lookup_p
)
{
AST_field_n_t *field_p;
unsigned long field_num;
field_num = attr_field_p->ir_info->id_num;
for (field_p = attr_field_p->next; field_p != NULL; field_p = field_p->next)
{
if (field_p->ir_info == NULL)
IR_INIT_INFO(field_p);
field_num++;
field_p->ir_info->id_num = field_num;
if (field_p == lookup_p)
return field_num;
}
return lookup_p->ir_info->id_num;
}
static void IR_gen_struct_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
unsigned long *field_num_p,
boolean *has_nf_cs_array
)
{
IR_tup_n_t *tup_p;
IR_tup_n_t *cs_tup_p = NULL;
IR_tup_n_t *pred_tup_p = NULL;
IR_tup_n_t *info_tup_p = NULL;
IR_tup_n_t *last_tup_p = NULL;
AST_structure_n_t *struct_p;
AST_field_n_t *field_p;
AST_field_n_t *last_field_p = NULL;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_struct_begin_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
IR_process_tup(ctx_p, tup_p);
if (AST_CONFORMANT_SET(type_p) && IR_in_struct(ctx_p) == 1)
{
tup_p->flags |= IR_CONFORMANT;
tup_p = info_tup_p = IR_gen_irep_tup(ctx_p, IR_op_conformant_info_k);
}
if (IR_in_struct(ctx_p) == 1)
{
pred_tup_p = tup_p;
cs_tup_p = IR_gen_irep_tup(ctx_p, IR_op_noop_k);
}
if (FE_TEST(type_p->fe_info->flags, FE_HAS_NF_CS_ARRAY))
*has_nf_cs_array = TRUE;
if (!AST_UNALIGN_SET(type_p) && IR_in_struct(ctx_p) == 1)
IR_gen_alignment(ctx_p, type_p->alignment_size);
struct_p = type_p->type_structure.structure;
for (field_p = struct_p->fields; field_p != NULL; field_p = field_p->next)
{
if (field_p->ir_info == NULL)
IR_INIT_INFO(field_p);
last_field_p = field_p;
last_tup_p = IR_cur_tup_p(ctx_p);
if (field_p->type->kind != AST_structure_k
|| field_p->type->xmit_as_type != NULL
|| field_p->type->rep_as_type != NULL
|| field_p->type->cs_char_type != NULL)
{
(*field_num_p)++;
field_p->ir_info->id_num = *field_num_p;
IR_gen_type_rep(ctx_p, field_p->type, (AST_instance_n_t *)field_p,
0);
}
else
{
if (!AST_UNALIGN_SET(field_p->type))
IR_gen_alignment(ctx_p, field_p->type->alignment_size);
IR_gen_struct_type_rep(ctx_p, field_p->type,
(AST_instance_n_t *)field_p, field_num_p, has_nf_cs_array);
}
}
if (AST_CONFORMANT_SET(type_p) && IR_in_struct(ctx_p) == 1)
{
while (last_tup_p != NULL
&& last_tup_p->opcode != IR_op_conformant_array_k
&& last_tup_p->opcode != IR_op_open_array_k)
last_tup_p = last_tup_p->next;
assert(last_tup_p != NULL);
if (last_field_p->type->type_structure.array->element_type->kind
== AST_array_k)
{
last_tup_p = last_tup_p->next;
while (last_tup_p != NULL
&& last_tup_p->opcode != IR_op_conformant_array_k
&& last_tup_p->opcode != IR_op_open_array_k)
last_tup_p = last_tup_p->next;
assert(last_tup_p != NULL);
}
assert (info_tup_p != NULL);
info_tup_p->arg[IR_ARG_TUP].tup = last_tup_p;
}
if (IR_in_struct(ctx_p) == 1)
{
if (*has_nf_cs_array)
{
assert (cs_tup_p != NULL);
cs_tup_p->opcode = IR_op_codeset_shadow_k;
cs_tup_p->arg[IR_ARG_INT].int_val = *field_num_p;
IR_gen_irep_tup(ctx_p, IR_op_release_shadow_k);
}
else
IR_free_irep_tup(ctx_p, cs_tup_p, pred_tup_p);
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_struct_end_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_struct_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
unsigned long start_num;
boolean has_nf_cs_array;
if (AST_SELF_POINTER_SET(type_p) && AST_DEF_AS_TAG_SET(type_p)
&& type_p->fe_info->original != NULL)
type_p = type_p->fe_info->original;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (type_p->ir_info == NULL)
{
IR_INIT_NODE(type_p);
IR_process_tup(ctx_p, tup_p);
start_num = 0;
has_nf_cs_array = FALSE;
IR_gen_struct_type_rep(ctx_p, type_p, inst_p, &start_num,
&has_nf_cs_array);
}
if (!AST_IN_SET(ctx_p->param_p)
&& type_p->ir_info->allocate_ref
&& !IR_under_pointer(ctx_p))
ctx_p->param_p->ir_info->allocate_ref = TRUE;
}
static int IR_case_info_compare
(
IR_case_info_n_t *p1,
IR_case_info_n_t *p2
)
{
if (p1->value < p2->value)
return -1;
else
return 1;
}
static void IR_gen_union_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p ATTRIBUTE_UNUSED
)
{
IR_tup_n_t *tup_p;
IR_tup_n_t *beg_tup_p;
AST_disc_union_n_t *union_p;
AST_arm_n_t *arm_p;
AST_case_label_n_t *label_p;
AST_constant_n_t *value_p;
AST_arm_n_t *default_p;
IR_case_info_n_t *array_p;
IR_case_info_n_t *beg_array_p;
IR_case_info_n_t *end_array_p;
long num_arms;
union_p = type_p->type_structure.disc_union;
beg_tup_p = IR_gen_irep_tup(ctx_p, IR_op_disc_union_begin_k);
beg_tup_p->arg[IR_ARG_TYPE].type = type_p;
if (union_p->discrim_name != NAMETABLE_NIL_ID)
beg_tup_p->flags |= IR_ENCAPSULATED;
IR_process_tup(ctx_p, beg_tup_p);
if (beg_tup_p->flags & IR_ENCAPSULATED)
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_switch_enc_k);
tup_p->arg[IR_ARG_NAME].name = union_p->discrim_name;
tup_p->arg[IR_ARG_TYPE].type = union_p->discrim_type;
}
num_arms = 0;
default_p = NULL;
for (arm_p = union_p->arms; arm_p != NULL; arm_p = arm_p->next)
{
for (label_p = arm_p->labels; label_p != NULL; label_p = label_p->next)
{
if (label_p->default_label)
default_p = arm_p;
else
num_arms++;
}
}
beg_tup_p->arg[IR_ARG_INT].int_val = num_arms;
if (num_arms != 0)
{
array_p = NEW_VEC (IR_case_info_n_t, num_arms);
beg_array_p = array_p;
end_array_p = array_p;
for (arm_p = union_p->arms; arm_p != NULL; arm_p = arm_p->next)
{
for (label_p = arm_p->labels; label_p != NULL; label_p = label_p->next)
{
if (label_p->default_label)
continue;
value_p = label_p->value;
switch (value_p->kind)
{
case AST_int_const_k:
end_array_p->value = (unsigned long)value_p->value.int_val;
break;
case AST_char_const_k:
end_array_p->value = (unsigned long)value_p->value.char_val;
break;
case AST_boolean_const_k:
end_array_p->value = (unsigned long)value_p->value.boolean_val;
break;
default:
INTERNAL_ERROR("Unsupported case label constant kind");
}
end_array_p->arm_p = arm_p;
end_array_p->label_p = label_p;
end_array_p++;
}
}
qsort(array_p, num_arms, sizeof(IR_case_info_n_t),
#if !(defined(mips) && defined(ultrix))
(int (*)(const void *, const void *))
#endif
IR_case_info_compare);
while (array_p < end_array_p)
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_case_k);
if (union_p->discrim_type->kind == AST_boolean_k)
tup_p->flags |= IR_BOOLEAN;
tup_p->arg[IR_ARG_INT].int_val = array_p->value;
if (array_p->arm_p->type == NULL)
tup_p->flags |= IR_VOID;
else
{
IR_gen_type_rep(ctx_p, array_p->arm_p->type,
(AST_instance_n_t *)array_p->arm_p, 0);
}
array_p++;
}
FREE(beg_array_p);
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_default_k);
if (default_p == NULL)
tup_p->arg[IR_ARG_TYPE].type = NULL;
else
{
tup_p->arg[IR_ARG_TYPE].type = default_p->type;
if (default_p->type == NULL)
tup_p->flags |= IR_VOID;
else
{
IR_gen_type_rep(ctx_p, default_p->type,
(AST_instance_n_t *)default_p, 0);
}
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_disc_union_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INT].int_val = num_arms;
tup_p->flags = beg_tup_p->flags;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_disc_union_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
AST_field_attr_n_t *fattr_p;
if (AST_SELF_POINTER_SET(type_p) && AST_DEF_AS_TAG_SET(type_p)
&& type_p->fe_info->original != NULL)
type_p = type_p->fe_info->original;
if (type_p->type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID)
{
fattr_p = inst_p->field_attrs;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_switch_n_e_k);
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->switch_is->ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->switch_is->ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (type_p->ir_info == NULL)
{
IR_INIT_NODE(type_p);
IR_process_tup(ctx_p, tup_p);
IR_gen_union_type_rep(ctx_p, type_p, inst_p);
}
}
static void IR_gen_interface_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_interface_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
tup_p->arg[IR_ARG_INTFC].intfc = type_p->type_structure.interface;
}
static IR_tup_n_t *IR_gen_ptr_tup
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
if ( (inst_p != NULL && AST_UNIQUE_SET(inst_p))
|| (inst_p == NULL && AST_UNIQUE_SET(type_p)) )
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_unique_ptr_k);
}
else if ( (inst_p != NULL && AST_PTR_SET(inst_p))
|| (inst_p == NULL && AST_PTR_SET(type_p)) )
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_full_ptr_k);
}
else if (IR_cur_scope(ctx_p) != IR_SCP_TOPLEVEL)
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_ref_ptr_k);
if (ctx_p->type_scope == 0)
{
if (!AST_IN_SET(ctx_p->param_p) && !IR_under_pointer(ctx_p))
ctx_p->param_p->ir_info->allocate_ref = TRUE;
}
else
{
ctx_p->type_s_a[ctx_p->type_scope].type_p->ir_info->allocate_ref
= TRUE;
}
}
else
tup_p = IR_gen_irep_tup(ctx_p, IR_op_passed_by_ref_k);
if (IR_STRING_ARRAY(type_p, inst_p) || IR_STRINGIFIED(type_p, inst_p))
tup_p->flags |= IR_STRING;
if (IR_ARRAYIFIED(type_p, inst_p))
tup_p->flags |= IR_ARRAYIFIED_PTR;
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
return tup_p;
}
static IR_tup_n_t *IR_gen_array_tup
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
)
{
IR_tup_n_t *tup_p;
boolean conformant, varying, string;
conformant = (AST_CONFORMANT_SET(type_p) != 0);
string = ((flags & IR_STRING) != 0);
varying = (string || (inst_p != NULL && AST_VARYING_SET(inst_p)));
if (conformant)
{
if (varying)
tup_p = IR_gen_irep_tup(ctx_p, IR_op_open_array_k);
else
tup_p = IR_gen_irep_tup(ctx_p, IR_op_conformant_array_k);
}
else
{
if (varying)
tup_p = IR_gen_irep_tup(ctx_p, IR_op_varying_array_k);
else
tup_p = IR_gen_irep_tup(ctx_p, IR_op_fixed_array_k);
}
tup_p->flags |= (flags & (IR_CS_CHAR|IR_STRING));
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
return tup_p;
}
static boolean IR_bound_early
(
IR_scope_ctx_t *ctx_p,
AST_instance_n_t *inst_p,
unsigned long attribute_index
)
{
unsigned long pf_index;
if (IR_under_struct(ctx_p))
{
pf_index = IR_field_num(ctx_p, (AST_field_n_t *)inst_p,
(AST_field_n_t *)inst_p);
}
else
{
pf_index = IR_param_num((AST_parameter_n_t *)inst_p);
}
return (attribute_index < pf_index);
}
static IR_tup_n_t *IR_gen_bound_tups
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
)
{
IR_tup_n_t *tup_p = NULL;
IR_tup_n_t *lower_tup_p = NULL;
AST_array_n_t *array_p = NULL;
AST_array_index_n_t *index_p;
AST_constant_n_t *const_p;
AST_field_attr_n_t *fattr_p;
int i;
boolean string;
string = ((flags & IR_STRING) != 0);
array_p = type_p->type_structure.array;
fattr_p = (inst_p == NULL) ? NULL : inst_p->field_attrs;
for (i = 0; i < array_p->index_count; i++)
{
index_p = &array_p->index_vec[i];
const_p = index_p->lower_bound;
lower_tup_p = tup_p = IR_gen_irep_tup(ctx_p, IR_op_bound_k);
if (fattr_p != NULL &&
fattr_p->min_is_vec != NULL && fattr_p->min_is_vec[i].valid)
{
if (fattr_p->min_is_vec[i].constant)
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->min_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_min_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->min_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->min_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = const_p->value.int_val;
}
const_p = index_p->upper_bound;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_bound_k);
if (const_p != NULL)
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = const_p->value.int_val;
}
else if (fattr_p != NULL &&
fattr_p->max_is_vec != NULL && fattr_p->max_is_vec[i].valid)
{
if (fattr_p->max_is_vec[i].constant)
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->max_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_max_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->max_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->max_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (fattr_p != NULL &&
fattr_p->size_is_vec != NULL && fattr_p->size_is_vec[i].valid)
{
if (fattr_p->size_is_vec[i].constant)
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = 0;
if (lower_tup_p->arg[IR_ARG_BOUND].bound_k == IR_bnd_fixed_k)
tup_p->arg[IR_ARG_INT].int_val += lower_tup_p->arg[IR_ARG_INT].int_val;
tup_p->arg[IR_ARG_INT].int_val += fattr_p->size_is_vec[i].ref.integer - 1;
}
else
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_size_is_k;
tup_p->flags |= (flags & IR_CS_CHAR);
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->size_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->size_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
tup_p->arg[IR_ARG_BOUND_XTRA].byt_val = fattr_p->size_is_vec[i].xtra_opcode;
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (string)
{
tup_p->arg[IR_ARG_BOUND].bound_k = IR_bnd_string_k;
if (type_p->type_structure.array->element_type->rep_as_type != NULL)
{
tup_p->flags |= IR_REP_AS;
tup_p->arg[IR_ARG_TYPE2].type =
type_p->type_structure.array->element_type;
}
else
{
tup_p->arg[IR_ARG_INT].int_val =
type_p->type_structure.array->element_type->ndr_size;
}
if (AST_CONFORMANT_SET(type_p)
&& IR_parent_scope(ctx_p) == IR_SCP_STRUCT)
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, (AST_field_n_t *)inst_p);
}
else
{
INTERNAL_ERROR("Invalid array bounds");
}
}
return tup_p;
}
static IR_tup_n_t *IR_gen_limit_tups
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
)
{
IR_tup_n_t *tup_p = NULL;
IR_tup_n_t *lower_tup_p = NULL;
AST_array_n_t *array_p;
AST_array_index_n_t *index_p;
AST_constant_n_t *const_p;
AST_field_attr_n_t *fattr_p;
int i;
boolean string;
string = ((flags & IR_STRING) != 0);
array_p = type_p->type_structure.array;
fattr_p = (inst_p == NULL) ? NULL : inst_p->field_attrs;
#if 0
printf("IR_gen_limit_tups: called with flags %08x string %d\n", flags, string);
#endif
for (i = 0; i < array_p->index_count; i++)
{
index_p = &array_p->index_vec[i];
const_p = index_p->lower_bound;
lower_tup_p = tup_p = IR_gen_irep_tup(ctx_p, IR_op_limit_k);
if (fattr_p != NULL && fattr_p->first_is_vec != NULL
&& fattr_p->first_is_vec[i].valid)
{
if (fattr_p->first_is_vec[i].constant)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->first_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_first_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->first_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->first_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (fattr_p != NULL && fattr_p->min_is_vec != NULL
&& fattr_p->min_is_vec[i].valid)
{
if (fattr_p->min_is_vec[i].constant)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->first_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_first_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->min_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->min_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = const_p->value.int_val;
}
const_p = index_p->upper_bound;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_limit_k);
if (string)
{
if (ctx_p->in_flat_rep)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = 0;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_string_k;
if (type_p->type_structure.array->element_type->rep_as_type != NULL)
{
tup_p->flags |= IR_REP_AS;
tup_p->arg[IR_ARG_TYPE2].type =
type_p->type_structure.array->element_type;
}
else
{
tup_p->arg[IR_ARG_INT].int_val =
type_p->type_structure.array->element_type->ndr_size;
}
}
}
else if (fattr_p != NULL && fattr_p->last_is_vec != NULL
&& fattr_p->last_is_vec[i].valid)
{
if (fattr_p->last_is_vec[i].constant)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->last_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_last_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->last_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->last_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (fattr_p != NULL && fattr_p->length_is_vec != NULL
&& fattr_p->length_is_vec[i].valid)
{
if (fattr_p->length_is_vec[i].constant)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = 0;
if (lower_tup_p->arg[IR_ARG_LIMIT].limit_k == IR_lim_fixed_k)
tup_p->arg[IR_ARG_INT].int_val += lower_tup_p->arg[IR_ARG_INT].int_val;
tup_p->arg[IR_ARG_INT].int_val += fattr_p->length_is_vec[i].ref.integer - 1;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_length_is_k;
tup_p->flags |= (flags & IR_CS_CHAR);
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->length_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->length_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
tup_p->arg[IR_ARG_BOUND_XTRA].byt_val = fattr_p->length_is_vec[i].xtra_opcode;
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (const_p == NULL
&& fattr_p != NULL
&& fattr_p->max_is_vec != NULL
&& fattr_p->max_is_vec[i].valid)
{
if (fattr_p->max_is_vec[i].constant)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = fattr_p->max_is_vec[i].ref.integer;
}
else
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_last_is_k;
if (IR_under_struct(ctx_p))
{
tup_p->arg[IR_ARG_FIELD].field = fattr_p->max_is_vec[i].ref.f_ref;
tup_p->arg[IR_ARG_PFNUM].int_val = IR_field_num(ctx_p,
(AST_field_n_t *)inst_p, tup_p->arg[IR_ARG_FIELD].field);
}
else
{
tup_p->arg[IR_ARG_PARAM].param = fattr_p->max_is_vec[i].ref.p_ref;
tup_p->arg[IR_ARG_PFNUM].int_val =
IR_param_num(tup_p->arg[IR_ARG_PARAM].param);
}
if (IR_bound_early(ctx_p, inst_p, tup_p->arg[IR_ARG_PFNUM].int_val))
tup_p->flags |= IR_CF_EARLY;
}
}
else if (const_p == NULL && fattr_p != NULL && fattr_p->size_is_vec != NULL
&& fattr_p->size_is_vec[i].valid)
{
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_upper_conf_k;
}
else
{
assert (tup_p != NULL);
assert (const_p != NULL);
tup_p->arg[IR_ARG_LIMIT].limit_k = IR_lim_fixed_k;
tup_p->arg[IR_ARG_INT].int_val = const_p->value.int_val;
}
}
return tup_p;
}
static void IR_gen_flat_array_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
AST_type_n_t *atype_p;
AST_type_n_t *btype_p;
AST_array_n_t *array_p;
unsigned short dim;
dim = 0;
for (atype_p = type_p;
atype_p->kind == AST_array_k
&& !AST_STRING_SET(atype_p) && !AST_STRING0_SET(atype_p);
atype_p = atype_p->type_structure.array->element_type)
{
array_p = atype_p->type_structure.array;
dim += array_p->index_count;
}
btype_p = atype_p;
if (btype_p->kind == AST_array_k)
dim++;
ctx_p->in_flat_rep = TRUE;
tup_p = IR_gen_array_tup(ctx_p, type_p, inst_p, 0);
IR_process_tup(ctx_p, tup_p);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_array_bounds_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INT].int_val = dim;
for (atype_p = type_p;
atype_p->kind == AST_array_k;
atype_p = atype_p->type_structure.array->element_type)
{
IR_gen_bound_tups(ctx_p, atype_p, (atype_p == type_p) ? inst_p : NULL,
(AST_STRING_SET(atype_p) || AST_STRING0_SET(atype_p)) ?
IR_STRING : 0);
}
if (inst_p != NULL && AST_VARYING_SET(inst_p))
{
for (atype_p = type_p;
atype_p->kind == AST_array_k;
atype_p = atype_p->type_structure.array->element_type)
{
IR_flags_t flags;
if (AST_STRING_SET(atype_p) || AST_STRING0_SET(atype_p))
flags = IR_STRING;
else
flags = 0;
IR_gen_limit_tups(ctx_p, atype_p,
(atype_p == type_p) ? inst_p : NULL,
flags);
}
}
ctx_p->in_flat_rep = FALSE;
IR_gen_type_rep(ctx_p, btype_p, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_array_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_array_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
)
{
IR_tup_n_t *tup_p;
AST_array_n_t *array_p;
AST_type_n_t *btype_p;
IR_tup_n_t *full_tup_p = NULL, *flat_tup_p;
boolean array_of_array;
boolean toplevel_array;
array_p = type_p->type_structure.array;
btype_p = array_p->element_type;
if (btype_p->cs_char_type != NULL)
flags |= IR_CS_CHAR;
if (IR_cur_scope(ctx_p) == IR_SCP_TOPLEVEL)
{
tup_p = IR_gen_ptr_tup(ctx_p, type_p, inst_p);
IR_process_tup(ctx_p, tup_p);
toplevel_array = TRUE;
}
else
toplevel_array = FALSE;
array_of_array = (IR_cur_scope(ctx_p) != IR_SCP_ARRAY
&& btype_p->kind == AST_array_k);
if (array_of_array)
full_tup_p = IR_gen_irep_tup(ctx_p, IR_op_full_array_k);
tup_p = IR_gen_array_tup(ctx_p, type_p, inst_p, flags);
IR_process_tup(ctx_p, tup_p);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_array_bounds_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INT].int_val = array_p->index_count;
IR_gen_bound_tups(ctx_p, type_p, inst_p, flags);
if ((flags & IR_STRING) || (inst_p != NULL && AST_VARYING_SET(inst_p)))
IR_gen_limit_tups(ctx_p, type_p, inst_p, flags);
IR_gen_type_rep(ctx_p, btype_p, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_array_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
IR_process_tup(ctx_p, tup_p);
if (array_of_array)
{
flat_tup_p = IR_gen_irep_tup(ctx_p, IR_op_flat_array_k);
IR_gen_flat_array_rep(ctx_p, type_p, inst_p);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_full_array_end_k);
full_tup_p->arg[IR_ARG_TUP].tup = flat_tup_p;
flat_tup_p->arg[IR_ARG_TUP].tup = tup_p;
}
if (toplevel_array)
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_pointee_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
IR_process_tup(ctx_p, tup_p);
}
}
static void IR_gen_multid_aos
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
AST_array_n_t *array_p;
AST_array_index_n_t *index_p;
AST_type_n_t *new_type_p;
AST_array_n_t *new_array_p;
AST_array_index_n_t *new_index_p;
AST_type_n_t *base_type_p;
AST_array_n_t *base_array_p;
AST_array_index_n_t *base_index_p;
int i;
array_p = type_p->type_structure.array;
index_p = array_p->index_vec;
new_type_p = AST_type_node(null_parser_location, AST_array_k);
base_type_p = AST_type_node(null_parser_location, AST_array_k);
new_array_p = AST_array_node(null_parser_location, base_type_p);
new_index_p = AST_array_index_node(null_parser_location, array_p->index_count-1);
new_type_p->name = type_p->name;
new_type_p->type_structure.array = new_array_p;
new_type_p->flags = type_p->flags;
new_type_p->fe_info->flags = type_p->fe_info->flags;
AST_CLR_STRING0(new_type_p);
if (inst_p != NULL) AST_CLR_STRING0(inst_p);
new_array_p->index_count = array_p->index_count-1;
new_array_p->index_vec = new_index_p;
for (i = 1; i < array_p->index_count; i++)
{
new_index_p->flags = index_p->flags;
new_index_p->lower_bound = index_p->lower_bound;
new_index_p->upper_bound = index_p->upper_bound;
new_index_p++;
index_p++;
}
base_array_p = AST_array_node(null_parser_location, array_p->element_type);
base_index_p = AST_array_index_node(null_parser_location, 1);
base_type_p->type_structure.array = base_array_p;
AST_SET_STRING0(base_type_p);
base_type_p->fe_info->flags = type_p->fe_info->flags;
base_array_p->index_count = 1;
base_array_p->index_vec = base_index_p;
base_index_p->flags = index_p->flags;
base_index_p->lower_bound = index_p->lower_bound;
base_index_p->upper_bound = index_p->upper_bound;
IR_gen_type_rep(ctx_p, new_type_p, inst_p, 0);
}
static void IR_gen_pointer_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
AST_type_n_t *arr_rep_type_p;
AST_type_n_t *ptee_type_p;
AST_instance_n_t *ptee_inst_p;
ptee_type_p = type_p->type_structure.pointer->pointee_type;
if (ptee_type_p->kind == AST_handle_k && ptee_type_p->xmit_as_type == NULL)
return;
if (inst_p && inst_p->type == type_p)
tup_p = IR_gen_ptr_tup(ctx_p, type_p, inst_p);
else
tup_p = IR_gen_ptr_tup(ctx_p, type_p, NULL);
IR_process_tup(ctx_p, tup_p);
if (tup_p->flags & IR_ARRAYIFIED_PTR)
{
arr_rep_type_p = ptee_type_p->array_rep_type;
if (FE_TEST(ptee_type_p->fe_info->flags, FE_HAS_PTR))
FE_SET(arr_rep_type_p->fe_info->flags, FE_HAS_PTR);
IR_gen_type_rep(ctx_p, arr_rep_type_p, inst_p, tup_p->flags);
}
else
{
if ( (ptee_type_p->kind == AST_disc_union_k && ptee_type_p->
type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID)
#if 1
||
(ptee_type_p->kind == AST_pointer_k &&
ptee_type_p->type_structure.pointer->pointee_type->kind ==
AST_disc_union_k)
#endif
||
((ptee_type_p->kind != AST_pointer_k || ptee_type_p->
type_structure.pointer->pointee_type->kind == AST_void_k
|| (ptee_type_p->type_structure.pointer->pointee_type->kind
== AST_structure_k && AST_CONTEXT_RD_SET(ptee_type_p)))
&& ptee_type_p->kind != AST_array_k
&& IR_parent_scope(ctx_p) == IR_SCP_TOPLEVEL) )
ptee_inst_p = inst_p;
else
ptee_inst_p = NULL;
IR_gen_type_rep(ctx_p, ptee_type_p, ptee_inst_p, 0);
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_pointee_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_xmit_as_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p ATTRIBUTE_UNUSED
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_transmit_as_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p->xmit_as_type;
tup_p->arg[IR_ARG_TYPE2].type = type_p;
IR_process_tup(ctx_p, tup_p);
IR_gen_type_rep(ctx_p, type_p->xmit_as_type, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_transmit_end_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p->xmit_as_type;
tup_p->arg[IR_ARG_TYPE2].type = type_p;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_xmit_as_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (type_p->ir_info == NULL)
{
IR_INIT_NODE(type_p);
IR_process_tup(ctx_p, tup_p);
IR_gen_xmit_as_type_rep(ctx_p, type_p, inst_p);
}
}
static void IR_gen_repr_as_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p ATTRIBUTE_UNUSED
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_represent_as_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_REP_AS].rep_as = type_p->rep_as_type;
IR_process_tup(ctx_p, tup_p);
IR_gen_type_rep(ctx_p, type_p, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_represent_end_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_REP_AS].rep_as = type_p->rep_as_type;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_repr_as_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
AST_rep_as_n_t *rep_p;
rep_p = type_p->rep_as_type;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->flags |= IR_REP_AS;
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (rep_p->ir_info == NULL)
{
IR_INIT_NODE(rep_p);
IR_process_tup(ctx_p, tup_p);
IR_gen_repr_as_type_rep(ctx_p, type_p, inst_p);
}
}
static void IR_gen_cs_char_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p ATTRIBUTE_UNUSED
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_cs_char_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_CS_CHAR].cs_char = type_p->cs_char_type;
IR_process_tup(ctx_p, tup_p);
IR_gen_type_rep(ctx_p, type_p, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_cs_char_end_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_CS_CHAR].cs_char = type_p->cs_char_type;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_cs_char_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
AST_cs_char_n_t *ichar_p;
ichar_p = type_p->cs_char_type;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->flags |= IR_CS_CHAR;
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (ichar_p->ir_info == NULL)
{
IR_INIT_NODE(ichar_p);
IR_process_tup(ctx_p, tup_p);
IR_gen_cs_char_type_rep(ctx_p, type_p, inst_p);
}
}
static void IR_gen_pipe_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p ATTRIBUTE_UNUSED
)
{
IR_tup_n_t *tup_p;
AST_pipe_n_t *pipe_p;
pipe_p = type_p->type_structure.pipe;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_pipe_begin_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_TYPE2].type = pipe_p->base_type;
IR_process_tup(ctx_p, tup_p);
IR_gen_type_rep(ctx_p, pipe_p->base_type, NULL, 0);
tup_p = IR_gen_irep_tup(ctx_p, IR_op_pipe_end_k);
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_TYPE2].type = pipe_p->base_type;
IR_process_tup(ctx_p, tup_p);
}
static void IR_gen_pipe_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_type_indirect_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
if (type_p->ir_info == NULL)
{
IR_INIT_NODE(type_p);
IR_process_tup(ctx_p, tup_p);
IR_gen_pipe_type_rep(ctx_p, type_p, inst_p);
}
}
static void IR_gen_context_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_parameter_n_t *param_p
)
{
IR_tup_n_t *tup_p;
tup_p = IR_gen_irep_tup(ctx_p, IR_op_context_handle_k);
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_PARAM].param = param_p;
}
static void IR_gen_scalar_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p
)
{
IR_tup_n_t *tup_p;
if (inst_p != NULL &&
inst_p->field_attrs != NULL &&
inst_p->field_attrs->range != NULL)
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_range_k);
tup_p->arg[IR_ARG_TUP].tup = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INT].int_val = inst_p->field_attrs->range->value[0];
tup_p->arg[IR_ARG_BOUND_XTRA].int_val = inst_p->field_attrs->range->value[1];
}
tup_p = IR_gen_irep_tup(ctx_p, IR_op_marshall_k);
if (inst_p != NULL
&& FE_TEST(inst_p->fe_info->flags, FE_USED_AS_CS_FLD_ATTR))
tup_p->flags |= IR_CS_CHAR;
tup_p->arg[IR_ARG_EXPR].expr = NULL;
tup_p->arg[IR_ARG_TYPE].type = type_p;
tup_p->arg[IR_ARG_INST].inst = inst_p;
}
static void IR_gen_type_rep
(
IR_scope_ctx_t *ctx_p,
AST_type_n_t *type_p,
AST_instance_n_t *inst_p,
IR_flags_t flags
)
{
if (type_p->rep_as_type != NULL && !IR_in_rep_as(ctx_p)
&& type_p->kind != AST_handle_k)
{
IR_gen_repr_as_rep(ctx_p, type_p, inst_p);
return;
}
if (type_p->xmit_as_type != NULL)
{
IR_gen_xmit_as_rep(ctx_p, type_p, inst_p);
return;
}
if (type_p->cs_char_type != NULL && !IR_in_cs_char(ctx_p))
{
IR_gen_cs_char_rep(ctx_p, type_p, inst_p);
return;
}
switch(type_p->kind)
{
case AST_boolean_k:
case AST_byte_k:
case AST_character_k:
case AST_small_integer_k:
case AST_short_integer_k:
case AST_long_integer_k:
case AST_hyper_integer_k:
case AST_small_unsigned_k:
case AST_short_unsigned_k:
case AST_long_unsigned_k:
case AST_hyper_unsigned_k:
case AST_short_float_k:
case AST_long_float_k:
case AST_enum_k:
IR_gen_scalar_rep(ctx_p, type_p, inst_p);
break;
case AST_void_k:
break;
case AST_handle_k:
break;
case AST_array_k:
if (type_p->type_structure.array->index_count > 1
&& inst_p != NULL && AST_STRING0_SET(inst_p))
{
IR_gen_multid_aos(ctx_p, type_p, inst_p);
}
else
{
if (IR_STRING_ARRAY(type_p, inst_p))
flags |= IR_STRING;
IR_gen_array_rep(ctx_p, type_p, inst_p, flags);
}
break;
case AST_structure_k:
IR_gen_struct_rep(ctx_p, type_p, inst_p);
break;
case AST_pipe_k:
IR_gen_pipe_rep(ctx_p, type_p, inst_p);
break;
case AST_pointer_k:
if (type_p->type_structure.pointer->pointee_type->kind == AST_void_k)
{
if (inst_p == NULL || !AST_CONTEXT_SET(inst_p))
{
INTERNAL_ERROR("void * in invalid context");
}
else
IR_gen_context_rep(ctx_p, type_p, (AST_parameter_n_t *)inst_p);
}
else if (AST_CONTEXT_RD_SET(type_p)
&& type_p->type_structure.pointer->pointee_type->kind
== AST_structure_k)
IR_gen_context_rep(ctx_p, type_p, (AST_parameter_n_t *)inst_p);
else if (type_p->type_structure.pointer->pointee_type->kind == AST_interface_k)
IR_gen_interface_rep(ctx_p, type_p->type_structure.pointer->pointee_type, inst_p);
else
IR_gen_pointer_rep(ctx_p, type_p, inst_p);
break;
case AST_function_k:
break;
case AST_disc_union_k:
IR_gen_disc_union_rep(ctx_p, type_p, inst_p);
break;
default:
INTERNAL_ERROR("Unexpected type kind");
}
}
void IR_gen_param_rep
(
AST_parameter_n_t *param_p
)
{
IR_scope_ctx_t *ctx_p;
IR_tup_n_t *tup_p;
ctx_p = IR_init_scope(param_p);
IR_INIT_NODE(param_p);
if (FE_TEST(param_p->fe_info->flags, FE_FIRST_IN_NF_CS_ARR)
|| FE_TEST(param_p->fe_info->flags, FE_FIRST_OUT_NF_CS_ARR))
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_codeset_shadow_k);
tup_p->arg[IR_ARG_INT].int_val = 0;
if (!FE_TEST(param_p->fe_info->flags, FE_FIRST_IN_NF_CS_ARR))
tup_p->flags |= IR_OUT_ONLY;
if (!FE_TEST(param_p->fe_info->flags, FE_FIRST_OUT_NF_CS_ARR))
tup_p->flags |= IR_IN_ONLY;
}
IR_gen_type_rep(ctx_p, param_p->type, (AST_instance_n_t *)param_p, 0);
if (FE_TEST(param_p->fe_info->flags, FE_LAST_IN_NF_CS_ARR)
|| FE_TEST(param_p->fe_info->flags, FE_LAST_OUT_NF_CS_ARR))
{
tup_p = IR_gen_irep_tup(ctx_p, IR_op_release_shadow_k);
if (!FE_TEST(param_p->fe_info->flags, FE_LAST_IN_NF_CS_ARR))
tup_p->flags |= IR_OUT_ONLY;
if (!FE_TEST(param_p->fe_info->flags, FE_LAST_OUT_NF_CS_ARR))
tup_p->flags |= IR_IN_ONLY;
}
IR_finish_scope(ctx_p);
}
boolean IR_gen_irep
(
boolean *cmd_opt ATTRIBUTE_UNUSED,
void **cmd_val ATTRIBUTE_UNUSED,
struct AST_interface_n_t *int_p
)
{
AST_export_n_t *export_p;
AST_operation_n_t *oper_p;
AST_parameter_n_t *param_p;
for (export_p = int_p->exports; export_p != NULL; export_p = export_p->next)
{
if (export_p->kind == AST_operation_k)
{
oper_p = export_p->thing_p.exported_operation;
for (param_p = oper_p->parameters;
param_p != NULL;
param_p = param_p->next)
{
IR_gen_param_rep(param_p);
}
IR_gen_param_rep(oper_p->result);
}
}
return TRUE;
}