#include <nidl.h>
#include <nametbl.h>
#include <errors.h>
#include <astp.h>
#include <nidlmsg.h>
#include <nidl_y.h>
#include <checker.h>
#include <message.h>
#include <backend.h>
#include <command.h>
#include <irep.h>
static AST_type_n_t *AST_propagate_typedef (
parser_location_p location,
AST_type_n_t *type_node_ptr,
ASTP_declarator_n_t *declarator_ptr,
ASTP_attributes_t *attributes
);
static AST_array_n_t *AST_propagate_array_type (
parser_location_p location,
AST_type_n_t *type_node_ptr,
AST_type_n_t *element_type_node_ptr,
ASTP_declarator_op_n_t *declarator_op_ptr
);
static void ASTP_verify_non_anonymous (
parser_location_p location,
AST_type_n_t *type,
ASTP_declarator_n_t *declarator_ptr
);
void ASTP_add_name_binding
(
parser_location_p location,
NAMETABLE_id_t name,
void *AST_node
)
{
char const *identifier;
ASTP_node_t const *binding;
char const *filename;
int issue_error;
int issue_case_warning ATTRIBUTE_UNUSED;
binding = NAMETABLE_lookup_binding(name);
if ((binding != NULL) && (binding->fe_info->node_kind == fe_constant_n_k))
issue_error = true;
else
issue_error = !NAMETABLE_add_binding (name, AST_node);
if (issue_error)
{
assert(NULL != binding);
NAMETABLE_id_to_string (name, &identifier);
if ((binding->fe_info != (fe_info_t *)NULL) &&
(binding->fe_info->source_line != 0) &&
(binding->fe_info->file != STRTAB_NULL_STR))
{
STRTAB_str_to_string(binding->fe_info->file, &filename);
log_error (location->lineno, NIDL_NAMEPREVDECLAT, identifier,
filename, binding->fe_info->source_line, NULL);
}
else
log_error (location->lineno, NIDL_NAMEALRDEC, identifier, NULL);
}
return;
}
void ASTP_validate_forward_ref
(
parser_location_p location,
AST_type_n_t *type
)
{
if (AST_DEF_AS_TAG_SET(type) &&
((type->kind == AST_disc_union_k) ||
(type->kind == AST_structure_k)) &&
(type->type_structure.structure == NULL))
{
char const *identifier;
NAMETABLE_id_to_string(type->fe_info->tag_name, &identifier);
log_error(location->lineno, NIDL_DEFNOTCOMP, identifier, NULL);
}
}
static void ASTP_validate_forward_ref_scope
(
parser_location_p location,
AST_type_n_t *type,
ASTP_node_t *parent_node
)
{
if (AST_DEF_AS_TAG_SET(type)
&& type->type_structure.structure == NULL
&& parent_node->fe_info->node_kind == fe_parameter_n_k)
{
char const *identifier;
NAMETABLE_id_to_string(type->fe_info->tag_name, &identifier);
log_warning(location->lineno, NIDL_FWDTAGREF, identifier, NULL);
}
}
AST_type_n_t *ASTP_chase_ptr_to_kind
(
AST_type_n_t *type_node,
AST_type_k_t kind
)
{
AST_type_n_t *tp;
short int pointer_count;
for (tp= type_node, pointer_count = 0;
(tp->kind != kind ) && (tp->kind == AST_pointer_k);
tp = tp->type_structure.pointer->pointee_type, pointer_count++)
{
}
if (tp->kind != kind)
{
tp = NULL;
}
else
{
tp->fe_info->pointer_count = pointer_count;
}
return tp;
}
AST_type_n_t *ASTP_chase_ptr_to_type
(
AST_type_n_t *type_node
)
{
AST_type_n_t *tp;
short int pointer_count;
for (tp= type_node, pointer_count = 0;
(tp->kind == AST_pointer_k);
tp = tp->type_structure.pointer->pointee_type, pointer_count++)
{
}
tp->fe_info->pointer_count = pointer_count;
return tp;
}
AST_constant_n_t *AST_clone_constant
(
parser_location_p location,
AST_constant_n_t *constant_node_p
)
{
AST_constant_n_t *new_const_node_p;
new_const_node_p = AST_constant_node (location, constant_node_p->kind);
switch (new_const_node_p->kind)
{
case AST_boolean_const_k:
new_const_node_p->value.boolean_val =
constant_node_p->value.boolean_val;
break;
case AST_char_const_k:
new_const_node_p->value.char_val =
constant_node_p->value.char_val;
break;
case AST_int_const_k:
new_const_node_p->value.int_val =
constant_node_p->value.int_val;
break;
case AST_string_const_k:
new_const_node_p->value.string_val =
constant_node_p->value.string_val;
break;
default:
break;
}
new_const_node_p->fe_info->fe_type_id =
constant_node_p->fe_info->fe_type_id;
new_const_node_p->fe_info->type_specific.const_kind =
constant_node_p->fe_info->type_specific.const_kind;
return new_const_node_p;
}
ASTP_node_t *AST_concat_element
(
ASTP_node_t *list_head,
ASTP_node_t *element
)
{
if (element == NULL)
{
return list_head;
}
if (list_head == NULL)
{
list_head = element;
return list_head;
}
if (list_head->last == NULL)
{
if (element->last == NULL)
{
list_head->last = element;
list_head->next = element;
return list_head;
}
list_head->last = element->last;
list_head->next = element;
return list_head;
}
list_head->last->next = element;
if (element->last != NULL)
{
list_head->last = element->last;
}
else
{
list_head->last = element;
}
return list_head;
}
ASTP_node_t *ASTP_lookup_binding
(
parser_location_p location,
NAMETABLE_id_t name,
fe_node_k_t node_kind,
boolean noforward_ref
)
{
ASTP_node_t *bound_node;
char const *identifier;
bound_node = (ASTP_node_t *) NAMETABLE_lookup_binding(name);
if ((bound_node == NULL) && noforward_ref)
{
NAMETABLE_id_to_string (name, &identifier);
log_error(location->lineno, NIDL_NAMENOTFND, identifier, NULL) ;
}
#if 0
if (node_kind == fe_type_n_k && bound_node &&
bound_node->fe_info->node_kind == fe_interface_n_k &&
AST_OBJECT_SET((AST_interface_n_t*)bound_node))
return bound_node->type_structure;
bound_node = (ASTP_node_t*)((AST_interface_n_t*)bound_node)->orpc_intf_type;
#endif
if ((bound_node != NULL) &&
(bound_node->fe_info->node_kind != node_kind))
{
if (noforward_ref)
{
NAMETABLE_id_to_string (name, &identifier);
switch (node_kind)
{
case fe_constant_n_k:
log_error(location->lineno, NIDL_NAMENOTCONST, identifier,
NULL) ;
break;
case fe_type_n_k:
log_error(location->lineno, NIDL_NAMENOTTYPE, identifier,
NULL) ;
break;
case fe_field_n_k:
log_error(location->lineno, NIDL_NAMENOTFIELD, identifier,
NULL) ;
break;
case fe_parameter_n_k:
log_error(location->lineno, NIDL_NAMENOTPARAM, identifier,
NULL) ;
break;
default:
break;
}
if ((bound_node->fe_info->source_line != 0) &&
(bound_node->fe_info->file != STRTAB_NULL_STR))
{
char const *filename;
STRTAB_str_to_string(bound_node->fe_info->file, &filename);
log_error (location->lineno, NIDL_NAMEPREVDECLAT, identifier,
filename, bound_node->fe_info->source_line, NULL);
}
}
bound_node = NULL;
}
return bound_node;
}
AST_pointer_n_t * AST_pointer_node
(
parser_location_p location,
AST_type_n_t * pointee
)
{
AST_pointer_n_t * pointer_node_ptr;
pointer_node_ptr = NEW (AST_pointer_n_t);
pointer_node_ptr->pointee_type = pointee;
ASTP_set_fe_info (location, &pointer_node_ptr->fe_info, fe_pointer_n_k);
return pointer_node_ptr;
}
AST_type_p_n_t *AST_declarators_to_types
(
parser_location_p location,
AST_interface_n_t * ifp,
AST_type_n_t *type_ptr,
ASTP_declarator_n_t *declarators_ptr,
ASTP_attributes_t *attributes
)
{
AST_type_p_n_t
*type_p_list = NULL,
*type_p_ptr;
ASTP_declarator_n_t
gen_declarator,
*base_dp = NULL,
*dp;
AST_type_n_t
*base_type = type_ptr;
for (dp = declarators_ptr;
dp != (ASTP_declarator_n_t *) NULL;
dp = dp->next)
{
if (dp->next_op == NULL)
{
base_dp = dp;
if ((type_ptr->fe_info->tag_ptr != NULL) &&
(type_ptr->fe_info->tag_ptr->name == NAMETABLE_NIL_ID))
type_ptr->fe_info->tag_ptr->name = base_dp->name;
break;
}
}
if ((base_dp == NULL) &&
(base_type->name == NAMETABLE_NIL_ID) &&
((base_type->kind == AST_structure_k) ||
(base_type->kind == AST_disc_union_k)) &&
(base_type->fe_info->tag_name == NAMETABLE_NIL_ID))
{
base_dp = &gen_declarator;
base_dp->name = AST_generate_name(ifp,"");
base_dp->next = NULL;
base_dp->last = NULL;
base_dp->next_op = NULL;
base_dp->last_op = NULL;
base_dp->fe_info = NULL;
}
if (base_dp != NULL)
{
ASTP_attributes_t local_attributes;
local_attributes = *attributes;
type_p_ptr = AST_type_ptr_node(location);
base_type = AST_propagate_typedef(location, type_ptr, base_dp, &local_attributes);
type_p_ptr->type = base_type;
type_p_list = (AST_type_p_n_t *)AST_concat_element (
(ASTP_node_t *)type_p_list, (ASTP_node_t *)type_p_ptr);
if (base_dp == &gen_declarator)
ASTP_CLR_ATTR(&local_attributes,ASTP_IGNORE|ASTP_PTR|ASTP_REF|
ASTP_UNIQUE|ASTP_STRING);
AST_set_type_attrs(location, type_p_ptr->type, &local_attributes);
if (type_p_ptr->type->fe_info->tag_ptr != NULL)
AST_set_type_attrs(location, type_p_ptr->type->fe_info->tag_ptr, &local_attributes);
}
for (dp = declarators_ptr;
dp != (ASTP_declarator_n_t *) NULL;
dp = dp->next)
{
if (dp == base_dp) continue;
type_p_ptr = AST_type_ptr_node(location);
type_p_ptr->type = AST_propagate_typedef(location, base_type, dp, attributes);
type_p_list = (AST_type_p_n_t *)AST_concat_element (
(ASTP_node_t *)type_p_list, (ASTP_node_t *)type_p_ptr);
AST_set_type_attrs(location, type_p_ptr->type, attributes);
if (type_p_ptr->type->fe_info->tag_ptr != NULL)
AST_set_type_attrs(location, type_p_ptr->type->fe_info->tag_ptr, attributes);
}
ASTP_free_declarators(declarators_ptr);
return type_p_list;
}
AST_array_n_t *AST_propagate_array_type
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
AST_type_n_t *element_type_node_ptr,
ASTP_declarator_op_n_t *declarator_op_ptr
)
{
AST_array_n_t *array_node_ptr;
ASTP_array_index_n_t *index_ptr;
AST_array_index_n_t *array_index_node;
unsigned short index_count;
boolean is_conformant = FALSE;
array_node_ptr = AST_array_node(location, element_type_node_ptr);
for (index_ptr = declarator_op_ptr->op_info.indices, index_count=0;
index_ptr != NULL;
index_ptr = index_ptr->next, index_count++)
{};
array_node_ptr->index_count = index_count;
array_node_ptr->index_vec = AST_array_index_node(location, index_count);
for (index_ptr = declarator_op_ptr->op_info.indices,
array_index_node = array_node_ptr->index_vec;
index_ptr != NULL;
index_ptr=index_ptr->next, array_index_node++)
{
if (index_ptr->lower_bound != NULL)
{
array_index_node->lower_bound = index_ptr->lower_bound;
AST_SET_FIXED_LOWER(array_index_node);
}
else
{
is_conformant = TRUE;
}
if (index_ptr->upper_bound != NULL)
{
array_index_node->upper_bound = index_ptr->upper_bound;
AST_SET_FIXED_UPPER(array_index_node);
}
else
{
is_conformant = TRUE;
}
}
if (is_conformant)
{
AST_SET_CONFORMANT(type_node_ptr);
}
return array_node_ptr;
}
static AST_type_n_t *AST_propagate_type_attrs
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
ASTP_attributes_t *attributes,
boolean needs_clone ATTRIBUTE_UNUSED,
ASTP_node_t *parent_node
)
{
AST_type_n_t *return_type;
ASTP_attr_flag_t ptr_attrs = 0;
return_type = type_node_ptr;
if (attributes != NULL)
{
return_type->iid_is_name = attributes->iid_is_name;
ptr_attrs = (attributes->attr_flags) & (ASTP_UNIQUE|ASTP_PTR|ASTP_REF);
if ((ptr_attrs != 0) &&
!((ptr_attrs == ASTP_REF) || (ptr_attrs == ASTP_PTR) ||
(ptr_attrs == ASTP_UNIQUE)))
{
ASTP_attr_flag_t attr1 = ASTP_REF;
ASTP_attr_flag_t attr2 = ASTP_PTR;
if (!ASTP_TEST_ATTR(attributes,ASTP_REF)) attr1 = ASTP_UNIQUE;
if (!ASTP_TEST_ATTR(attributes,ASTP_PTR)) attr2 = ASTP_UNIQUE;
log_error(location->lineno, NIDL_CONFLICTATTR,
KEYWORDS_lookup_text(AST_attribute_to_token(&attr1)),
KEYWORDS_lookup_text(AST_attribute_to_token(&attr2)), NULL);
}
if (return_type->name == NAMETABLE_NIL_ID)
{
if (ASTP_TEST_ATTR(attributes,ASTP_UNALIGN))
AST_SET_UNALIGN(return_type);
if (ASTP_TEST_ATTR(attributes,ASTP_SMALL))
AST_SET_SMALL(return_type);
if (ASTP_TEST_ATTR(attributes,ASTP_STRING0))
AST_SET_STRING0(return_type);
if (ASTP_TEST_ATTR(attributes,ASTP_V1_ENUM))
AST_SET_V1_ENUM(return_type);
if (ASTP_TEST_ATTR(attributes,ASTP_SWITCH_TYPE))
{
if (return_type->kind == AST_disc_union_k
&& return_type->type_structure.disc_union->discrim_name
== NAMETABLE_NIL_ID
&& (parent_node->fe_info->node_kind == fe_parameter_n_k
|| parent_node->fe_info->node_kind == fe_field_n_k))
{
return_type->type_structure.disc_union->discrim_type
= ASTP_switch_type;
ASTP_CLR_ATTR(attributes,ASTP_SWITCH_TYPE);
}
}
ASTP_CLR_ATTR(attributes,ASTP_UNALIGN|ASTP_SMALL|ASTP_STRING0|ASTP_V1_ENUM);
}
}
if (parent_node->fe_info->node_kind == fe_parameter_n_k)
{
if (ptr_attrs != 0)
{
if (((return_type->name == NAMETABLE_NIL_ID) &&
(return_type->kind == AST_pointer_k)) ||
(return_type->kind == AST_array_k))
{
}
else
{
log_error(location->lineno, NIDL_PRMBYREF,
KEYWORDS_lookup_text(AST_attribute_to_token(&ptr_attrs)),
NULL);
}
}
else
{
if (((return_type->name == NAMETABLE_NIL_ID) &&
(return_type->kind == AST_pointer_k)) ||
(return_type->kind == AST_array_k))
{
if (!((return_type->kind == AST_pointer_k) &&
(return_type->type_structure.pointer->pointee_type->kind == AST_void_k) ))
{
if (return_type->type_structure.pointer->pointee_type->kind != AST_interface_k)
AST_SET_REF(((AST_parameter_n_t*)parent_node));
}
}
else
{
if (AST_PTR_SET(return_type))
AST_SET_PTR((AST_parameter_n_t *)parent_node);
if (AST_REF_SET(return_type))
AST_SET_REF((AST_parameter_n_t *)parent_node);
if (AST_UNIQUE_SET(return_type))
AST_SET_UNIQUE((AST_parameter_n_t *)parent_node);
}
}
if (AST_SMALL_SET(return_type))
AST_SET_SMALL((AST_parameter_n_t *)parent_node);
if (AST_STRING_SET(return_type))
AST_SET_STRING((AST_parameter_n_t *)parent_node);
if (AST_STRING0_SET(return_type))
AST_SET_STRING0((AST_parameter_n_t *)parent_node);
}
if ((parent_node->fe_info->node_kind == fe_field_n_k) ||
(parent_node->fe_info->node_kind == fe_arm_n_k))
{
if (ptr_attrs == 0)
{
if (AST_PTR_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_PTR((AST_field_n_t *)parent_node);
else
AST_SET_PTR((AST_arm_n_t *)parent_node);
}
if (AST_REF_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_REF((AST_field_n_t *)parent_node);
else
AST_SET_REF((AST_arm_n_t *)parent_node);
}
if (AST_UNIQUE_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_UNIQUE((AST_field_n_t *)parent_node);
else
AST_SET_UNIQUE((AST_arm_n_t *)parent_node);
}
}
else
{
if (return_type->name != NAMETABLE_NIL_ID)
{
if (ASTP_TEST_ATTR(attributes,ASTP_REF))
log_error(location->lineno,NIDL_REFATTRPTR, NULL);
if (ASTP_TEST_ATTR(attributes,ASTP_PTR))
log_error(location->lineno,NIDL_PTRATTRPTR, NULL);
if (ASTP_TEST_ATTR(attributes,ASTP_UNIQUE))
log_error(location->lineno,NIDL_UNIQATTRPTR, NULL);
}
}
if (AST_SMALL_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_SMALL((AST_field_n_t *)parent_node);
else
AST_SET_SMALL((AST_arm_n_t *)parent_node);
}
if (AST_STRING_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_STRING((AST_field_n_t *)parent_node);
else
AST_SET_STRING((AST_arm_n_t *)parent_node);
}
if (AST_STRING0_SET(return_type))
{
if (parent_node->fe_info->node_kind == fe_field_n_k)
AST_SET_STRING0((AST_field_n_t *)parent_node);
else
AST_SET_STRING0((AST_arm_n_t *)parent_node);
}
if (AST_IGNORE_SET(return_type) &&
(parent_node->fe_info->node_kind == fe_field_n_k))
{
AST_SET_IGNORE((AST_field_n_t *)parent_node);
}
}
return return_type;
}
static AST_type_n_t *AST_propagate_typedef
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
ASTP_declarator_n_t *declarator_ptr,
ASTP_attributes_t *attributes
)
{
AST_type_n_t *return_type;
AST_type_n_t *current_type;
ASTP_declarator_op_n_t *dop;
if (declarator_ptr->next_op == NULL)
{
if ((type_node_ptr->name == NAMETABLE_NIL_ID) &&
!type_is_base(type_node_ptr) &&
!AST_DEF_AS_TAG_SET(type_node_ptr))
{
return_type = type_node_ptr;
}
else
{
return_type = AST_type_node(location, type_node_ptr->kind);
return_type->type_structure = type_node_ptr->type_structure;
return_type->flags = type_node_ptr->flags;
return_type->xmit_as_type = type_node_ptr->xmit_as_type;
if (ASTP_TEST_ATTR(attributes, ASTP_TRANSMIT_AS))
{
AST_CLR_STRING(return_type); AST_CLR_STRING0(return_type);
AST_CLR_UNIQUE(return_type); AST_CLR_REF(return_type);
AST_CLR_IGNORE(return_type); AST_CLR_SMALL(return_type);
AST_CLR_CONTEXT_RD(return_type);AST_CLR_PTR(return_type);
}
}
if ((type_node_ptr->name != NAMETABLE_NIL_ID) &&
!AST_DEF_AS_TAG_SET(type_node_ptr))
return_type->defined_as = type_node_ptr;
return_type->fe_info->tag_ptr = type_node_ptr->fe_info->tag_ptr;
return_type->fe_info->tag_name = type_node_ptr->fe_info->tag_name;
if (FE_TEST(type_node_ptr->fe_info->flags,FE_INCOMPLETE))
{
FE_SET(return_type->fe_info->flags,FE_INCOMPLETE);
ASTP_save_tag_ref(type_node_ptr->fe_info->tag_name,
type_node_ptr->kind,return_type);
}
}
else
{
return_type = type_node_ptr;
for (dop = declarator_ptr->next_op; dop; dop = dop->next_op)
{
current_type = return_type;
switch (dop->op_kind)
{
case AST_array_k:
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.array =
AST_propagate_array_type(location,
return_type, current_type, dop);
break;
case AST_pointer_k:
{
int i;
for (i = dop->op_info.pointer_count; i > 0; i--)
{
boolean is_void = (current_type->kind == AST_void_k);
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.pointer =
AST_pointer_node(location, current_type);
current_type = return_type;
if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS)) continue;
if (ASTP_TEST_ATTR(attributes,ASTP_CONTEXT)) continue;
if (is_void) continue;
if ((dop->next_op == NULL) && (i == 1) &&
(ASTP_TEST_ATTR(attributes,ASTP_PTR|ASTP_REF|
ASTP_UNIQUE) != 0))
continue;
if (current_type->type_structure.pointer->pointee_type->kind == AST_interface_k)
continue;
switch (the_interface->pointer_default)
{
case 0:
if (!AST_LOCAL_SET(the_interface))
{
char const *identifier;
NAMETABLE_id_to_string (
declarator_ptr->name, &identifier);
log_warning(location->lineno,
NIDL_MISSPTRCLASS, identifier,
NULL);
AST_SET_PTR(return_type);
}
break;
case ASTP_PTR: AST_SET_PTR(return_type); break;
case ASTP_REF: AST_SET_REF(return_type); break;
case ASTP_UNIQUE:AST_SET_UNIQUE(return_type); break;
default:
error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__);
}
}
break;
}
case AST_function_k:
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.function =
AST_function_node(location,
current_type, declarator_ptr->name,
dop->op_info.routine_params);
break;
default:
error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__);
break;
}
return_type->fe_info->tag_ptr = type_node_ptr->fe_info->tag_ptr;
return_type->fe_info->tag_name = type_node_ptr->fe_info->tag_name;
if (FE_TEST(type_node_ptr->fe_info->flags,FE_INCOMPLETE))
{
FE_SET(return_type->fe_info->flags,FE_INCOMPLETE);
ASTP_save_tag_ref(type_node_ptr->fe_info->tag_name,
type_node_ptr->kind,return_type);
}
}
}
return_type->name = declarator_ptr->name;
ASTP_add_name_binding (location, return_type->name, return_type);
return return_type;
}
AST_type_n_t *AST_propagate_type
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
ASTP_declarator_n_t *declarator_ptr,
ASTP_attributes_t *attributes,
ASTP_node_t *parent_node
)
{
AST_type_n_t *return_type;
AST_type_n_t *current_type;
ASTP_declarator_op_n_t *dop;
enum
{
simple_type,
complex_type
} last_op_kind;
return_type = type_node_ptr;
last_op_kind = simple_type;
ASTP_validate_forward_ref_scope(location, type_node_ptr, parent_node);
for (dop = declarator_ptr->next_op; dop; dop = dop->next_op)
{
last_op_kind = complex_type;
current_type = return_type;
switch (dop->op_kind)
{
case AST_array_k:
ASTP_validate_forward_ref(location, current_type);
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.array =
AST_propagate_array_type(location,
return_type, current_type, dop);
break;
case AST_pointer_k:
{
int i;
for (i = dop->op_info.pointer_count; i > 0; i--)
{
boolean is_void = (current_type->kind == AST_void_k);
ASTP_verify_non_anonymous(location, current_type, declarator_ptr);
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.pointer =
AST_pointer_node(location, current_type);
current_type = return_type;
if (parent_node->fe_info->node_kind == fe_operation_n_k)
continue;
if (parent_node->fe_info->node_kind == fe_constant_n_k)
continue;
if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS)) continue;
if (ASTP_TEST_ATTR(attributes,ASTP_CONTEXT)) continue;
if (is_void) continue;
if ((dop->next_op == NULL) && (i == 1) && (ASTP_TEST_ATTR(
attributes,ASTP_PTR|ASTP_REF|ASTP_UNIQUE) != 0))
continue;
if ((dop->next_op == NULL) && (i == 1) &&
(parent_node->fe_info->node_kind == fe_parameter_n_k))
continue;
if (current_type->type_structure.pointer->pointee_type->kind == AST_interface_k)
continue;
switch (the_interface->pointer_default)
{
case 0:
if (!AST_LOCAL_SET(the_interface))
{
char const *identifier;
NAMETABLE_id_to_string (
declarator_ptr->name, &identifier);
log_warning(location->lineno, NIDL_MISSPTRCLASS,
identifier, NULL);
AST_SET_PTR(return_type);
}
break;
case ASTP_PTR: AST_SET_PTR(return_type); break;
case ASTP_REF: AST_SET_REF(return_type); break;
case ASTP_UNIQUE:AST_SET_UNIQUE(return_type); break;
default:
error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__);
}
}
break;
}
case AST_function_k:
ASTP_validate_forward_ref(location, current_type);
return_type = AST_type_node(location, dop->op_kind);
return_type->type_structure.function =
AST_function_node(location,
current_type, declarator_ptr->name,
dop->op_info.routine_params);
break;
default:
error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__);
break;
}
}
return_type =
AST_propagate_type_attrs(location, return_type, attributes,
(boolean)(last_op_kind == simple_type),
(ASTP_node_t *)parent_node);
return return_type;
}
static void ASTP_save_field_ref_context
(
NAMETABLE_id_t name,
AST_field_ref_n_t *field_ref_addr,
fe_info_t *fe_info
)
{
ASTP_field_ref_ctx_t *field_ref_ctx_ptr;
field_ref_ctx_ptr = NEW (ASTP_field_ref_ctx_t);
field_ref_ctx_ptr->fe_info = fe_info;
field_ref_ctx_ptr->name = name;
field_ref_ctx_ptr->field_ref_ptr = field_ref_addr;
ASTP_field_ref_ctx_list = (ASTP_field_ref_ctx_t *)
AST_concat_element((ASTP_node_t *)ASTP_field_ref_ctx_list,
(ASTP_node_t *)field_ref_ctx_ptr);
return;
}
void ASTP_set_array_rep_type
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
AST_type_n_t *array_base_type,
boolean is_varying
)
{
char *identifier ATTRIBUTE_UNUSED;
AST_type_p_n_t *tp_node ATTRIBUTE_UNUSED;
if (type_node_ptr->kind == AST_pointer_k)
{
if (type_node_ptr->type_structure.pointer->pointee_type->array_rep_type == NULL)
{
AST_type_n_t *array_rep_of_pointer;
AST_array_n_t *array_node;
array_node = AST_array_node(location, array_base_type);
array_node->index_count = 1;
array_node->index_vec = AST_array_index_node(location, 1);
array_node->index_vec->lower_bound = zero_constant_p;
AST_SET_FIXED_LOWER(array_node->index_vec);
array_rep_of_pointer = AST_type_node(location, AST_array_k);
array_rep_of_pointer->type_structure.array = array_node;
AST_SET_CONFORMANT(array_rep_of_pointer);
type_node_ptr->type_structure.pointer->pointee_type->array_rep_type = array_rep_of_pointer;
if (AST_DEF_AS_TAG_SET(type_node_ptr->type_structure.pointer->pointee_type) &&
(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original != NULL) &&
(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type == NULL))
{
ASTP_set_array_rep_type(location, type_node_ptr,
type_node_ptr->type_structure.pointer->pointee_type->fe_info->original,
is_varying);
}
}
if (is_varying)
{
AST_SET_VARYING(type_node_ptr->type_structure.pointer->pointee_type->array_rep_type);
if (AST_DEF_AS_TAG_SET(type_node_ptr->type_structure.pointer->pointee_type) &&
(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original != NULL) &&
(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type != NULL))
{
AST_SET_VARYING(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type);
}
}
}
}
boolean AST_lookup_field_attr
(
ASTP_attributes_t *attributes,
ASTP_attr_k_t field_attr
)
{
ASTP_type_attr_n_t *bound_p;
for (bound_p = attributes->bounds; bound_p != NULL; bound_p = bound_p->next)
{
if (bound_p->kind == field_attr)
return TRUE;
}
return FALSE;
}
AST_field_attr_n_t *AST_set_field_attrs
(
parser_location_p location,
ASTP_attributes_t *attributes,
ASTP_node_t *parent_node,
AST_type_n_t *type_node
)
{
AST_field_attr_n_t
*field_attr_node;
AST_field_ref_n_t
*field_ref_vector = NULL;
ASTP_type_attr_n_t
*attr_ptr,
*next_attr_ptr;
ASTP_node_t
*referent_node;
AST_type_n_t
*clone_type ATTRIBUTE_UNUSED,
*tp;
unsigned short
dimension = 0,
index_count;
boolean pointer_as_array = FALSE,
noforward_ref = TRUE;
ASTP_attr_k_t
current_attr_kind;
boolean array_attr_valid = TRUE;
boolean neu_attr_valid = FALSE;
if ((attributes->bounds == NULL) && !ASTP_TEST_ATTR(attributes,(ASTP_STRING)))
return (AST_field_attr_n_t *)NULL;
tp = ASTP_chase_ptr_to_kind(type_node, AST_disc_union_k);
if (tp != NULL
&& ( (tp->type_structure.disc_union != NULL
&& tp->type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID)
|| (FE_TEST(tp->fe_info->flags, FE_INCOMPLETE)
&& AST_lookup_field_attr(attributes, switch_is_k)) ))
{
dimension = 1;
array_attr_valid = FALSE;
neu_attr_valid = TRUE;
}
else
{
tp = ASTP_chase_ptr_to_kind(type_node, AST_array_k);
if (tp == NULL)
{
if (((parent_node->fe_info->node_kind == fe_field_n_k) &&
(type_node->kind != AST_pointer_k)) ||
((parent_node->fe_info->node_kind == fe_parameter_n_k) &&
((type_node->kind != AST_pointer_k)||
(type_node->name != NAMETABLE_NIL_ID))))
{
if (attributes->bounds != NULL)
{
if (attributes->bounds->kind == range_k)
{
AST_exp_n_t *exp;
field_attr_node = AST_field_attr_node(location);
field_attr_node->range = NEW(AST_tuple_n_t);
exp = attributes->bounds->b.expr;
field_attr_node->range->value[0] =
ASTP_expr_integer_value(location, exp->exp.expression.oper1);
field_attr_node->range->value[1] =
ASTP_expr_integer_value(location, exp->exp.expression.oper2);
if (field_attr_node->range->value[0] > field_attr_node->range->value[1])
log_error(location->lineno, NIDL_INVALIDRANGE, NULL);
return field_attr_node;
}
else if (attributes->bounds->kind == switch_is_k)
log_error(location->lineno, NIDL_SWATTRNEU, NULL);
else
log_error(location->lineno, NIDL_SIZEARRTYPE, NULL);
}
return (AST_field_attr_n_t *)NULL;
}
}
if (tp != NULL)
{
dimension = tp->type_structure.array->index_count;
}
else if (type_node->kind == AST_pointer_k)
{
tp = type_node;
while(tp->type_structure.pointer->pointee_type->kind == AST_pointer_k && tp->kind != AST_interface_k)
tp = tp->type_structure.pointer->pointee_type;
dimension = 1;
pointer_as_array = TRUE;
ASTP_set_array_rep_type(location, type_node,
type_node->type_structure.pointer->pointee_type,
FALSE);
}
if (attributes->bounds == NULL)
{
ASTP_set_array_rep_type(location, type_node,
type_node->type_structure.pointer->pointee_type,
TRUE);
return (AST_field_attr_n_t *)NULL;
}
}
field_attr_node = AST_field_attr_node(location);
for (attr_ptr=attributes->bounds;
attr_ptr != NULL;
attr_ptr= attr_ptr->next)
{
if (attr_ptr->kind != switch_is_k && !array_attr_valid)
{
log_error(location->lineno, NIDL_SIZEARRTYPE, NULL);
return (AST_field_attr_n_t *)NULL;
}
if (attr_ptr->kind == switch_is_k && !neu_attr_valid)
{
log_error(location->lineno, NIDL_SWATTRNEU, NULL);
return (AST_field_attr_n_t *)NULL;
}
switch (attr_ptr->kind)
{
case iid_is_k:
if (field_attr_node->iid_is == NULL)
{
field_attr_node->iid_is =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->iid_is;
break;
case first_is_k:
if (field_attr_node->first_is_vec == NULL)
{
field_attr_node->first_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->first_is_vec;
break;
case last_is_k:
if (field_attr_node->last_is_vec == NULL)
{
field_attr_node->last_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->last_is_vec;
break;
case length_is_k:
if (field_attr_node->length_is_vec == NULL)
{
field_attr_node->length_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->length_is_vec;
break;
case min_is_k:
if (field_attr_node->min_is_vec == NULL)
{
field_attr_node->min_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->min_is_vec;
break;
case max_is_k:
if (field_attr_node->max_is_vec == NULL)
{
field_attr_node->max_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->max_is_vec;
break;
case size_is_k:
if (field_attr_node->size_is_vec == NULL)
{
field_attr_node->size_is_vec =
AST_field_ref_node(location, dimension);
}
field_ref_vector = field_attr_node->size_is_vec;
break;
case switch_is_k:
if (field_attr_node->switch_is == NULL)
{
field_attr_node->switch_is =
AST_field_ref_node(location, 1);
}
field_ref_vector = field_attr_node->switch_is;
break;
default:
break;
}
if ((attr_ptr->kind == last_is_k) ||
(attr_ptr->kind == length_is_k) ||
(attr_ptr->kind == first_is_k))
{
if (parent_node->fe_info->node_kind == fe_parameter_n_k)
{
AST_SET_VARYING((AST_parameter_n_t*)parent_node);
}
else
{
AST_SET_VARYING((AST_field_n_t*)parent_node);
}
if (pointer_as_array)
{
ASTP_set_array_rep_type(location, type_node,
type_node->type_structure.pointer->pointee_type,
TRUE);
}
}
current_attr_kind = attr_ptr->kind;
next_attr_ptr = attr_ptr;
index_count = 0;
do
{
assert(field_ref_vector != NULL);
if (index_count >= dimension)
{
log_error(location->lineno, NIDL_SIZEMISMATCH, NULL);
break;
}
attr_ptr = next_attr_ptr;
if (attr_ptr->is_expr || attr_ptr->b.simple.name != NAMETABLE_NIL_ID)
{
AST_exp_n_t * exp = NULL;
if (attr_ptr->is_expr)
{
exp = attr_ptr->b.expr;
if (ASTP_expr_is_simple(location, exp))
{
while(exp->exp_type == AST_EXP_UNARY_STAR)
{
field_ref_vector->fe_info->pointer_count++;
exp = attr_ptr->b.expr = exp->exp.expression.oper1;
}
switch(exp->exp_type)
{
case AST_EXP_CONSTANT:
break;
case AST_EXP_BINARY_SLASH:
switch (ASTP_expr_integer_value(location, exp->exp.expression.oper2))
{
case 8: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_8; break;
case 4: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_4; break;
case 2: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_2; break;
default: log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL); return NULL;
}
exp = exp->exp.expression.oper1;
break;
case AST_EXP_BINARY_STAR:
switch (ASTP_expr_integer_value(location, exp->exp.expression.oper2))
{
case 8: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_8; break;
case 4: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_4; break;
case 2: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_2; break;
default: log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL); return NULL;
}
exp = exp->exp.expression.oper1;
break;
case AST_EXP_BINARY_PLUS:
field_ref_vector->xtra_opcode = IR_EXP_FC_ADD_1;
exp = exp->exp.expression.oper1;
break;
case AST_EXP_BINARY_MINUS:
field_ref_vector->xtra_opcode = IR_EXP_FC_SUB_1;
exp = exp->exp.expression.oper1;
break;
case AST_EXP_BINARY_AND:
switch(ASTP_expr_integer_value(location, exp->exp.expression.oper1->exp.expression.oper2))
{
case 1:
field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_2;
break;
case 3:
field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_4;
break;
case 7:
field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_4;
break;
}
exp = exp->exp.expression.oper1->exp.expression.oper1;
while(exp->exp_type == AST_EXP_UNARY_STAR)
{
field_ref_vector->fe_info->pointer_count++;
exp = attr_ptr->b.expr = exp->exp.expression.oper1;
}
break;
}
if (exp->exp_type != AST_EXP_CONSTANT)
{
log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL);
return NULL;
}
else if (exp->exp.constant.type != AST_nil_const_k)
{
field_ref_vector->constant = true;
field_ref_vector->ref.integer =
ASTP_expr_integer_value(location, exp);
}
else
{
field_ref_vector->constant = false;
}
attr_ptr->is_expr = false;
attr_ptr->b.simple.name = exp->exp.constant.name;
}
else
{
log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL) ;
return NULL;
}
}
else if (attr_ptr->b.simple.pointer)
{
field_ref_vector->fe_info->pointer_count = 1;
}
if ((parent_node->fe_info->node_kind == fe_parameter_n_k) ||
(parent_node->fe_info->node_kind == fe_field_n_k))
{
noforward_ref = FALSE;
}
referent_node = (ASTP_node_t *)
ASTP_lookup_binding(location, attr_ptr->b.simple.name,
parent_node->fe_info->node_kind,
noforward_ref);
if (referent_node != NULL)
{
field_ref_vector->valid = TRUE;
if (parent_node->fe_info->node_kind == fe_parameter_n_k)
{
field_ref_vector->ref.p_ref =
(AST_parameter_n_t *)referent_node;
}
else
{
field_ref_vector->ref.f_ref =
(AST_field_n_t *)referent_node;
}
}
else if (field_ref_vector->constant == true)
{
field_ref_vector->valid = true;
}
else
{
if ((parent_node->fe_info->node_kind == fe_parameter_n_k) ||
(parent_node->fe_info->node_kind == fe_field_n_k))
{
ASTP_save_field_ref_context(
attr_ptr->b.simple.name,
field_ref_vector,
parent_node->fe_info);
}
else
{
char const *identifier;
NAMETABLE_id_to_string (attr_ptr->b.simple.name,
&identifier);
log_error(location->lineno, NIDL_NAMENOTFND, identifier, NULL) ;
}
}
}
next_attr_ptr = next_attr_ptr->next;
field_ref_vector++;
index_count++;
}
while ( (attr_ptr->next != NULL) &&
(attr_ptr->next->kind == current_attr_kind)) ;
}
return field_attr_node;
}
AST_type_n_t *AST_set_type_attrs
(
parser_location_p location,
AST_type_n_t *type_node_ptr,
ASTP_attributes_t *attributes
)
{
AST_type_p_n_t *tp_node;
AST_set_flags(location, &type_node_ptr->flags,(ASTP_node_t *)type_node_ptr, attributes);
if (AST_V1_ENUM_SET(type_node_ptr))
{
type_node_ptr->ndr_size = 4;
type_node_ptr->alignment_size = type_node_ptr->ndr_size;
}
if (ASTP_TEST_ATTR(attributes,(ASTP_STRING)) &&
(type_node_ptr->kind == AST_pointer_k))
{
ASTP_set_array_rep_type(location, type_node_ptr,
type_node_ptr->type_structure.pointer->pointee_type,
TRUE);
}
if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS))
{
type_node_ptr->xmit_as_type = ASTP_transmit_as_type;
if (type_node_ptr->xmit_as_type == NULL)
INTERNAL_ERROR("ASTP_transmit_as_type is NULL when attribute set");
}
if (ASTP_TEST_ATTR(attributes,ASTP_SWITCH_TYPE))
{
if (type_node_ptr->kind != AST_disc_union_k)
log_error(location->lineno, NIDL_SWTYPENEU, NULL);
else if (type_node_ptr->type_structure.disc_union == NULL)
ASTP_validate_forward_ref(location, type_node_ptr);
else if (type_node_ptr->type_structure.disc_union->discrim_name
!= NAMETABLE_NIL_ID)
log_error(location->lineno, NIDL_SWTYPENEU, NULL);
else
{
type_node_ptr->type_structure.disc_union->discrim_type
= ASTP_switch_type;
if (ASTP_switch_type == NULL)
INTERNAL_ERROR("ASTP_switch_type is NULL when attribute set");
}
}
if (type_node_ptr->kind == AST_pipe_k)
{
tp_node = AST_type_ptr_node(location);
tp_node->type = type_node_ptr;
the_interface->pipe_types = (AST_type_p_n_t *)
AST_concat_element((ASTP_node_t *)the_interface->pipe_types,
(ASTP_node_t *)tp_node);
}
return type_node_ptr;
}
void ASTP_free_declarators
(
ASTP_declarator_n_t *declarators_ptr
)
{
ASTP_declarator_n_t
*dp,
*next_dp;
ASTP_declarator_op_n_t
*dop,
*next_dop;
ASTP_array_index_n_t
*index_node,
*next_index;
for (dp = declarators_ptr, next_dp = declarators_ptr;
next_dp != (ASTP_declarator_n_t *) NULL;
dp= next_dp)
{
next_dp = dp->next;
for (dop = dp->next_op, next_dop = dp->next_op;
next_dop != NULL;
dop = next_dop)
{
if (dop->op_kind == AST_array_k)
{
for (index_node = dop->op_info.indices, next_index = dop->op_info.indices;
next_index != NULL;
index_node = next_index)
{
next_index = index_node->next;
FREE(index_node);
}
}
next_dop = dop->next_op;
FREE(dop);
}
FREE(dp);
}
return;
}
void ASTP_free_simple_list
(
ASTP_node_t *list_ptr
)
{
ASTP_node_t *lp,
*next_lp;
for (lp = list_ptr, next_lp = list_ptr;
next_lp != (ASTP_node_t *) NULL;
lp = next_lp)
{
next_lp = lp->next;
FREE(lp);
}
return;
}
void ASTP_patch_field_reference
(
parser_location_p location
)
{
ASTP_field_ref_ctx_t *field_ref_ctx;
AST_parameter_n_t *parameter_node_ptr;
AST_field_n_t *field_node_ptr;
for (field_ref_ctx = ASTP_field_ref_ctx_list;
field_ref_ctx != NULL;
field_ref_ctx = field_ref_ctx->next)
{
if (field_ref_ctx->fe_info->node_kind == fe_parameter_n_k)
{
parameter_node_ptr = (AST_parameter_n_t *)
ASTP_lookup_binding(location, field_ref_ctx->name,
fe_parameter_n_k, TRUE);
if (parameter_node_ptr != NULL)
{
field_ref_ctx->field_ref_ptr->ref.p_ref = parameter_node_ptr;
field_ref_ctx->field_ref_ptr->valid = TRUE;
}
}
if (field_ref_ctx->fe_info->node_kind == fe_field_n_k)
{
field_node_ptr = (AST_field_n_t *)
ASTP_lookup_binding(location, field_ref_ctx->name,
fe_field_n_k, TRUE);
if (field_node_ptr != NULL)
{
field_ref_ctx->field_ref_ptr->ref.f_ref = field_node_ptr;
field_ref_ctx->field_ref_ptr->valid = TRUE;
}
}
}
ASTP_field_ref_ctx_list = NULL;
return;
}
void ASTP_set_fe_info
(
parser_location_p location,
fe_info_t **fe_info_ptr,
fe_node_k_t fe_node_kind
)
{
fe_info_t *fe_info;
fe_info = *fe_info_ptr = BE_ctx_malloc(sizeof (fe_info_t));
fe_info->source_line = location->lineno;
fe_info->file = location->fileid;
fe_info->acf_source_line = 0;
fe_info->acf_file = 0;
fe_info->node_kind = fe_node_kind;
fe_info->fe_type_id = fe_source_only;
fe_info->tag_ptr = NULL;
fe_info->tag_name = NAMETABLE_NIL_ID;
fe_info->gen_index = 0;
fe_info->pointer_count = 0;
fe_info->flags = 0;
fe_info->original = NULL;
}
void ASTP_save_tag_ref
(
NAMETABLE_id_t identifier,
AST_type_k_t kind,
AST_type_n_t *type_node_ptr
)
{
ASTP_tag_ref_n_t *tag_ref_node_ptr;
if ((type_node_ptr->kind != AST_structure_k) &&
(type_node_ptr->kind != AST_disc_union_k)) return;
tag_ref_node_ptr = NEW (ASTP_tag_ref_n_t);
tag_ref_node_ptr->ref_kind = kind;
tag_ref_node_ptr->name = identifier;
tag_ref_node_ptr->type_node_ptr = type_node_ptr;
ASTP_tag_ref_list = (ASTP_tag_ref_n_t *)
AST_concat_element((ASTP_node_t *)ASTP_tag_ref_list,
(ASTP_node_t *)tag_ref_node_ptr);
FE_SET(type_node_ptr->fe_info->flags,FE_INCOMPLETE);
}
static void ASTP_process_context_type
(
AST_type_n_t *type_node_ptr
)
{
AST_SET_CONTEXT_RD(type_node_ptr);
}
void AST_set_flags
(
parser_location_p location,
AST_flags_t *flags,
ASTP_node_t *node_ptr,
ASTP_attributes_t *attributes
)
{
#define COPY_IF_LARGER(a,b) {if ((b) > (a)) (a) = (b);}
ASTP_type_attr_n_t *bp;
ASTP_attr_flag_t current_attribute;
ASTP_attr_flag_t valid_attr_flags;
long message_number = 0;
boolean bounds_illegal = TRUE;
switch (node_ptr->fe_info->node_kind)
{
case fe_field_n_k:
valid_attr_flags = ASTP_FIELD_FLAGS;
message_number = NIDL_ILLFIELDATTR;
bounds_illegal = FALSE;
break;
case fe_arm_n_k:
valid_attr_flags = ASTP_ARM_FLAGS;
message_number = NIDL_ILLMEMATTR;
break;
case fe_type_n_k:
valid_attr_flags = ASTP_TYPE_FLAGS;
message_number = NIDL_ILLTYPEATTR;
break;
case fe_parameter_n_k:
valid_attr_flags = ASTP_PARAMETER_FLAGS;
message_number = NIDL_ILLPARAMATTR;
bounds_illegal = FALSE;
break;
case fe_operation_n_k:
valid_attr_flags = ASTP_OPERATION_FLAGS;
message_number = NIDL_ILLOPATTR;
break;
case fe_interface_n_k:
valid_attr_flags = 0;
message_number = NIDL_ILLINTATTR;
break;
default:
valid_attr_flags = 0;
break;
}
for (current_attribute = 1;
current_attribute != 0 && current_attribute <= (unsigned) ASTP_MAX_ATTRIBUTE;
current_attribute <<= 1)
{
if (ASTP_TEST_ATTR(attributes,current_attribute))
{
if ((current_attribute & ~valid_attr_flags) == 0)
{
switch (current_attribute)
{
case ASTP_BROADCAST:
*flags |= (AST_BROADCAST | AST_IDEMPOTENT); break;
case ASTP_MAYBE:
*flags |= (AST_MAYBE | AST_IDEMPOTENT); break;
case ASTP_IDEMPOTENT:
*flags |= AST_IDEMPOTENT; break;
case ASTP_REFLECT_DELETIONS:
*flags |= AST_REFLECT_DELETIONS; break;
case ASTP_LOCAL:
*flags |= AST_LOCAL; break;
case ASTP_IN:
*flags |= AST_IN; break;
case ASTP_IN_SHAPE:
*flags |= AST_IN_SHAPE; break;
case ASTP_OUT:
*flags |= AST_OUT; break;
case ASTP_OUT_SHAPE:
*flags |= AST_OUT_SHAPE; break;
case ASTP_STRING:
*flags |= AST_STRING; break;
case ASTP_STRING0:
*flags |= AST_STRING0; break;
case ASTP_UNIQUE:
*flags |= AST_UNIQUE; break;
case ASTP_REF:
*flags |= AST_REF; break;
case ASTP_PTR:
*flags |= AST_PTR; break;
case ASTP_V1_ENUM:
*flags |= AST_V1_ENUM; break;
case ASTP_IGNORE:
*flags |= AST_IGNORE; break;
case ASTP_SMALL:
*flags |= AST_SMALL; break;
case ASTP_HANDLE:
*flags |= AST_HANDLE; break;
case ASTP_UNALIGN:
*flags |= AST_UNALIGN; break;
case ASTP_ALIGN_SMALL:
case ASTP_ALIGN_SHORT:
case ASTP_ALIGN_LONG:
case ASTP_ALIGN_HYPER:
{
log_error(location->lineno, NIDL_NYSALIGN, NULL);
#if 0
AST_type_n_t *type_node_ptr = (AST_type_n_t *)node_ptr;
switch (current_attribute)
{
case ASTP_ALIGN_SMALL:
COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_SMALL_INT_SIZE)
break;
case ASTP_ALIGN_SHORT:
COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_SHORT_INT_SIZE)
break;
case ASTP_ALIGN_LONG:
COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_LONG_INT_SIZE)
break;
case ASTP_ALIGN_HYPER:
COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_HYPER_INT_SIZE)
break;
}
if (!((node_ptr->fe_info->node_kind == fe_type_n_k) &&
(type_node_ptr->kind == AST_array_k) &&
(type_node_ptr->type_structure.array != NULL) &&
(type_node_ptr->type_structure.array->index_count == 1) &&
(type_node_ptr->type_structure.array->element_type->kind == AST_byte_k)))
{
log_error(location->lineno, NIDL_ALIGNBYTEARRAY, NULL);
}
#endif
break;
}
case ASTP_CONTEXT:
{
if (node_ptr->fe_info->node_kind == fe_type_n_k)
ASTP_process_context_type((AST_type_n_t *)node_ptr);
else
*flags |= AST_CONTEXT;
break;
}
case ASTP_TRANSMIT_AS:
break;
case ASTP_SWITCH_TYPE:
break;
case ASTP_RANGE:
break;
default:
error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__);
}
}
else
{
log_error(location->lineno, message_number,
KEYWORDS_lookup_text(AST_attribute_to_token(¤t_attribute)), NULL);
}
}
}
if (bounds_illegal)
for (bp = attributes->bounds; bp; bp = bp->next)
{
long token = 0;
switch (bp->kind)
{
case last_is_k: token = LAST_IS_KW; break;
case first_is_k: token = FIRST_IS_KW; break;
case max_is_k: token = MAX_IS_KW; break;
case length_is_k: token = LENGTH_IS_KW; break;
case size_is_k: token = SIZE_IS_KW; break;
case switch_is_k: token = SWITCH_IS_KW; break;
case min_is_k: token = MIN_IS_KW; break;
case iid_is_k: token = IID_IS_KW; break;
case range_k: token = RANGE_KW; break;
}
log_error(location->lineno, message_number, KEYWORDS_lookup_text(token), NULL) ;
}
}
long AST_attribute_to_token
(
ASTP_attr_flag_t *attribute
)
{
switch (*attribute)
{
case ASTP_ALIGN_SMALL: return ALIGN_KW;
case ASTP_ALIGN_SHORT: return ALIGN_KW;
case ASTP_ALIGN_LONG: return ALIGN_KW;
case ASTP_ALIGN_HYPER: return ALIGN_KW;
case ASTP_BROADCAST: return BROADCAST_KW;
case ASTP_MAYBE: return MAYBE_KW;
case ASTP_IDEMPOTENT: return IDEMPOTENT_KW;
case ASTP_REFLECT_DELETIONS: return REFLECT_DELETIONS_KW;
case ASTP_IN: return IN_KW;
case ASTP_OUT: return OUT_KW;
case ASTP_STRING: return STRING_KW;
case ASTP_STRING0: return V1_STRING_KW;
case ASTP_IN_SHAPE: return IN_KW;
case ASTP_OUT_SHAPE: return OUT_KW;
case ASTP_UNIQUE: return UNIQUE_KW;
case ASTP_PTR: return PTR_KW;
case ASTP_REF: return REF_KW;
case ASTP_IGNORE: return IGNORE_KW;
case ASTP_SMALL: return V1_ARRAY_KW;
case ASTP_HANDLE: return HANDLE_KW;
case ASTP_CONTEXT: return CONTEXT_HANDLE_KW;
case ASTP_TRANSMIT_AS: return TRANSMIT_AS_KW;
case ASTP_UNALIGN: return V1_STRUCT_KW;
case ASTP_V1_ENUM: return V1_ENUM_KW;
case ASTP_CASE: return CASE_KW;
case ASTP_DEFAULT: return DEFAULT_KW;
case ASTP_SWITCH_TYPE: return SWITCH_TYPE_KW;
default: return 0;
}
}
NAMETABLE_id_t AST_generate_name
(
AST_interface_n_t *int_p,
const char *suffix
)
{
char gen_name[MAX_ID+1];
char const *int_name;
NAMETABLE_id_to_string(int_p->name, &int_name);
sprintf(gen_name, "%s_v%ld_%ld_%ld%s", int_name, int_p->version%65536,
int_p->version/65536, int_p->fe_info->gen_index++,suffix);
if (strlen(gen_name) > MAX_ID)
message_print(NIDL_NAMETOOLONG, nidl_yylineno);
return NAMETABLE_add_id(gen_name);
}
void ASTP_validate_integer
(
parser_location_p location,
AST_exp_n_t *exp_node
)
{
if (!ASTP_evaluate_expr(location, exp_node, true)) {
log_error(location->lineno, NIDL_NONINTEXP, NULL);
return;
}
if (exp_node->exp.constant.type != AST_int_const_k)
{
switch (exp_node->exp.constant.val.other->kind)
{
case AST_int_const_k:
exp_node->exp.constant.type = AST_int_const_k;
exp_node->exp.constant.val.integer = exp_node->exp.constant.val.other->value.int_val;
break;
case AST_char_const_k:
exp_node->exp.constant.type = AST_int_const_k;
exp_node->exp.constant.val.integer = exp_node->exp.constant.val.other->value.char_val;
break;
default:
exp_node->exp.constant.type = AST_int_const_k;
exp_node->exp.constant.val.integer = 0;
log_error(location->lineno,NIDL_NONINTEXP, NULL);
break;
}
}
}
static void ASTP_verify_non_anonymous
(
parser_location_p location,
AST_type_n_t *type,
ASTP_declarator_n_t *declarator_ptr
)
{
if (!AST_DEF_AS_TAG_SET(type) &&
(type->name == NAMETABLE_NIL_ID) &&
(((type->kind == AST_disc_union_k) &&
(type->type_structure.disc_union != NULL) &&
(type->type_structure.disc_union->tag_name == NAMETABLE_NIL_ID))
||
((type->kind == AST_structure_k) &&
(type->type_structure.structure != NULL) &&
(type->type_structure.structure->tag_name == NAMETABLE_NIL_ID))))
{
char const *identifier;
NAMETABLE_id_to_string(declarator_ptr->name, &identifier);
log_warning(location->lineno, NIDL_ANONTYPE, identifier, NULL);
}
}
void ASTP_set_implicit_handle(
AST_interface_n_t *int_p,
NAMETABLE_id_t type_name,
NAMETABLE_id_t handle_name
)
{
if (type_name != NAMETABLE_NIL_ID) {
AST_type_n_t * type_p;
type_p = (AST_type_n_t*)NAMETABLE_lookup_binding(type_name);
if (type_p != NULL && type_p->fe_info->node_kind == fe_type_n_k)
{
int_p->implicit_handle_name = handle_name;
int_p->implicit_handle_type = type_p;
int_p->implicit_handle_type_name = type_p->name;
if (AST_HANDLE_SET(type_p))
AST_SET_IMPLICIT_HANDLE_G(int_p);
}
else {
int_p->implicit_handle_type_name = type_name;
int_p->implicit_handle_type = NULL;
int_p->implicit_handle_name = handle_name;
AST_SET_IMPLICIT_HANDLE_G(int_p);
}
}
else {
int_p->implicit_handle_name = handle_name;
int_p->implicit_handle_type = ASTP_handle_ptr;
}
}