#include <nidl.h>
#include <nametbl.h>
#include <errors.h>
#include <astp.h>
#include <nidlmsg.h>
#include <nidl_y.h>
static void AST_synthesize_param_to_oper_attr (
AST_parameter_n_t *parameter_node,
AST_operation_n_t *operation_node,
ASTP_parameter_count_t *param_count
);
static void AST_set_oper_has_ins_outs (
AST_operation_n_t *operation_node,
ASTP_parameter_count_t *param_count
);
ASTP_type_attr_n_t *AST_array_bound_info
(
parser_location_p location,
NAMETABLE_id_t name,
ASTP_attr_k_t kind,
boolean is_pointer
)
{
ASTP_type_attr_n_t *attr_node_p;
attr_node_p = NEW (ASTP_type_attr_n_t);
attr_node_p->is_expr = false;
attr_node_p->kind = kind ;
attr_node_p->b.simple.name = name;
attr_node_p->b.simple.pointer = is_pointer;
attr_node_p->source_line = location->lineno ;
return attr_node_p ;
}
ASTP_type_attr_n_t * AST_array_bound_from_expr
(
parser_location_p location,
AST_exp_n_t * exp,
ASTP_attr_k_t kind
)
{
ASTP_type_attr_n_t *attr_node_p;
attr_node_p = NEW (ASTP_type_attr_n_t);
attr_node_p->is_expr = true;
attr_node_p->kind = kind ;
attr_node_p->b.expr = exp;
attr_node_p->source_line = location->lineno ;
return attr_node_p ;
}
ASTP_type_attr_n_t * AST_range_from_expr
(
parser_location_p location,
AST_exp_n_t * exp_low_val,
AST_exp_n_t * exp_high_val
)
{
ASTP_type_attr_n_t *attr_node_p;
attr_node_p = NEW (ASTP_type_attr_n_t);
attr_node_p->is_expr = true;
attr_node_p->kind = range_k;
attr_node_p->b.expr = AST_expression(location,
AST_EXP_TUPLE,
exp_low_val,
exp_high_val,
NULL);
attr_node_p->source_line = location->lineno;
return attr_node_p;
}
AST_constant_n_t *AST_boolean_constant
(
parser_location_p location,
boolean value
)
{
AST_constant_n_t *const_node_ptr;
const_node_ptr = AST_constant_node(location, AST_boolean_const_k);
const_node_ptr->value.boolean_val = value;
return const_node_ptr;
}
AST_constant_n_t *AST_char_constant
(
parser_location_p location,
char value
)
{
AST_constant_n_t *const_node_ptr;
const_node_ptr = AST_constant_node(location, AST_char_const_k);
const_node_ptr->value.char_val = value;
return const_node_ptr;
}
AST_constant_n_t *AST_constant_node
(
parser_location_p location,
AST_constant_k_t kind
)
{
AST_constant_n_t *constant_node_p;
constant_node_p = NEW (AST_constant_n_t);
constant_node_p->name = NAMETABLE_NIL_ID;
constant_node_p->kind = kind;
ASTP_set_fe_info (location, &constant_node_p->fe_info, fe_constant_n_k);
return constant_node_p;
}
static AST_operation_n_t *AST_create_operation_node
(
parser_location_p location,
NAMETABLE_id_t op_name,
AST_parameter_n_t *parameters
)
{
AST_operation_n_t *operation_node_p;
operation_node_p = NEW (AST_operation_n_t);
ASTP_set_fe_info (location, &operation_node_p->fe_info, fe_operation_n_k);
operation_node_p->name = op_name;
operation_node_p->parameters = parameters;
return(operation_node_p);
}
ASTP_declarator_n_t *AST_declarator_node
(
NAMETABLE_id_t name
)
{
ASTP_declarator_n_t *declarator_node_ptr;
declarator_node_ptr = NEW (ASTP_declarator_n_t );
declarator_node_ptr->name = name;
return declarator_node_ptr;
}
void AST_declarator_operation
(
ASTP_declarator_n_t *declarator,
AST_type_k_t op_kind,
ASTP_node_t *op_info,
int pointer_count
)
{
ASTP_declarator_op_n_t *declarator_op;
if ((op_kind == AST_array_k) && (declarator->next_op != NULL) &&
(declarator->next_op->op_kind == AST_array_k))
{
declarator->next_op->op_info.indices = (ASTP_array_index_n_t *)
AST_concat_element ((ASTP_node_t *)declarator->next_op->op_info.indices,
(ASTP_node_t *)op_info);
return;
}
declarator_op = NEW (ASTP_declarator_op_n_t);
declarator_op->op_kind = op_kind;
if (op_kind == AST_pointer_k)
declarator_op->op_info.pointer_count = pointer_count;
else
declarator_op->op_info.node = op_info;
declarator_op->next_op = declarator->next_op;
declarator->next_op = declarator_op;
if (declarator->last_op == NULL)
declarator->last_op = declarator->next_op;
return;
}
AST_parameter_n_t *AST_declarator_to_param
(
parser_location_p location,
ASTP_attributes_t *attributes,
AST_type_n_t *type,
ASTP_declarator_n_t *declarator
)
{
AST_parameter_n_t *new_parameter;
AST_type_n_t *new_type;
if (!AST_DEF_AS_TAG_SET(type) &&
((type->kind == AST_disc_union_k) ||
(type->kind == AST_structure_k)) &&
(type->name == NAMETABLE_NIL_ID))
{
char const *identifier;
NAMETABLE_id_to_string(declarator->name, &identifier);
log_error(location->lineno, NIDL_ANONTYPE, identifier, NULL);
}
new_parameter = AST_parameter_node (location, declarator->name);
new_type = AST_propagate_type(location, type, declarator, attributes,
(ASTP_node_t *)new_parameter);
new_parameter->type = new_type;
ASTP_validate_forward_ref(location, new_type);
new_parameter->field_attrs =
AST_set_field_attrs(location, attributes, (ASTP_node_t *)new_parameter,
new_parameter->type);
AST_set_flags(location, &new_parameter->flags,
(ASTP_node_t *)new_parameter, attributes);
if (attributes)
new_type->iid_is_name = attributes->iid_is_name;
ASTP_add_name_binding (location, new_parameter->name, new_parameter);
ASTP_free_declarators(declarator);
return new_parameter;
}
AST_type_n_t *AST_enumerator_node
(
parser_location_p location,
AST_constant_n_t *constant_list,
AST_type_k_t size ATTRIBUTE_UNUSED
)
{
AST_enumeration_n_t *enum_node_ptr;
AST_type_n_t *type_node_ptr;
unsigned int N = 0;
AST_constant_n_t *cp;
int overflow = FALSE;
for (cp = constant_list; cp; cp = cp->next)
{
if (cp->value.int_val != 0)
N = cp->value.int_val + 1;
else
cp->value.int_val = N++;
if ((unsigned int)N >= ASTP_C_SHORT_MAX) overflow = TRUE;
}
if (overflow)
log_error(location->lineno, NIDL_TOOMANYELEM, "enum", NULL) ;
enum_node_ptr = NEW (AST_enumeration_n_t);
type_node_ptr = AST_type_node(location, AST_enum_k);
enum_node_ptr->enum_constants = constant_list;
type_node_ptr->type_structure.enumeration = enum_node_ptr;
ASTP_set_fe_info (location, &enum_node_ptr->fe_info, fe_enumeration_n_k);
return type_node_ptr;
}
AST_export_n_t *AST_export_node
(
parser_location_p location,
ASTP_node_t *export_ptr,
AST_export_k_t kind
)
{
AST_export_n_t *export_node_ptr;
if (export_ptr == NULL) return NULL;
export_node_ptr = NEW (AST_export_n_t);
export_node_ptr->kind = kind;
switch (kind)
{
case AST_cpp_quote_k:
export_node_ptr->thing_p.exported_cpp_quote =
(AST_cpp_quote_n_t *) export_ptr;
break;
case AST_constant_k:
export_node_ptr->thing_p.exported_constant =
(AST_constant_n_t *) export_ptr;
break;
case AST_operation_k:
export_node_ptr->thing_p.exported_operation =
(AST_operation_n_t *) export_ptr;
break;
case AST_type_k:
export_node_ptr->thing_p.exported_type =
(AST_type_n_t *) export_ptr;
break;
default:
break;
}
ASTP_set_fe_info (location, &export_node_ptr->fe_info, fe_export_n_k);
return export_node_ptr;
}
AST_cpp_quote_n_t *AST_cpp_quote_node
(
parser_location_p location,
STRTAB_str_t text
)
{
AST_cpp_quote_n_t *cpp_quote_node_ptr;
cpp_quote_node_ptr = NEW (AST_cpp_quote_n_t);
cpp_quote_node_ptr->text = text;
ASTP_set_fe_info (location, &cpp_quote_node_ptr->fe_info, fe_cpp_quote_n_k);
return cpp_quote_node_ptr;
}
AST_constant_n_t *AST_finish_constant_node
(
parser_location_p location,
AST_constant_n_t *constant_ptr,
ASTP_declarator_n_t *declarator,
AST_type_n_t *type_ptr
)
{
boolean type_check_failed = false;
AST_type_n_t *result_type;
AST_constant_n_t *return_constant;
ASTP_attributes_t no_attrs;
no_attrs.bounds = NULL;
no_attrs.attr_flags = ASTP_PTR;
no_attrs.iid_is_name = NAMETABLE_NIL_ID;
result_type = AST_propagate_type(location,
type_ptr, declarator, &no_attrs,
(ASTP_node_t *)constant_ptr);
if (constant_ptr->name != NAMETABLE_NIL_ID)
{
return_constant = AST_clone_constant(location, constant_ptr);
return_constant->defined_as = constant_ptr;
}
else
{
return_constant = constant_ptr;
}
return_constant->name = declarator->name;
ASTP_add_name_binding (location, return_constant->name, return_constant);
switch (return_constant->kind)
{
case AST_nil_const_k:
if (!((result_type->kind == AST_pointer_k) &&
(result_type->type_structure.pointer->pointee_type->kind ==
AST_void_k)))
{
type_check_failed = true;
}
break;
case AST_int_const_k:
switch (result_type->kind)
{
case AST_small_integer_k:
if ((constant_ptr->value.int_val > ASTP_C_SMALL_MAX) ||
(constant_ptr->value.int_val < ASTP_C_SMALL_MIN))
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(SMALL_KW), NULL);
}
break;
case AST_small_unsigned_k:
if ((constant_ptr->value.int_val > ASTP_C_USMALL_MAX) ||
(constant_ptr->value.int_val < ASTP_C_USMALL_MIN))
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(SMALL_KW), NULL);
}
break;
case AST_short_integer_k:
if ((constant_ptr->value.int_val > ASTP_C_SHORT_MAX) ||
(constant_ptr->value.int_val < ASTP_C_SHORT_MIN))
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(SHORT_KW), NULL);
}
break;
case AST_short_unsigned_k:
if ((constant_ptr->value.int_val > ASTP_C_USHORT_MAX) ||
(constant_ptr->value.int_val < ASTP_C_USHORT_MIN))
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(SHORT_KW), NULL);
}
break;
case AST_long_integer_k:
if ((constant_ptr->value.int_val > ASTP_C_LONG_MAX) ||
(constant_ptr->value.int_val < ASTP_C_LONG_MIN))
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(LONG_KW), NULL);
}
break;
case AST_long_unsigned_k:
if (((unsigned int)constant_ptr->value.int_val > ASTP_C_ULONG_MAX)
#if ASTP_C_ULONG_MIN > 0
|| ((unsigned int)constant_ptr->value.int_val < ASTP_C_ULONG_MIN)
#endif
)
{
log_error(location->lineno, NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(LONG_KW), NULL);
}
break;
case AST_hyper_integer_k:
case AST_hyper_unsigned_k:
log_error (location->lineno, NIDL_HYPERCONST, NULL);
break;
default:
type_check_failed = true;
break;
}
break;
case AST_hyper_int_const_k:
if (!(result_type->kind == AST_hyper_integer_k) ||
(result_type->kind == AST_hyper_unsigned_k))
{
type_check_failed = true;
}
break;
case AST_char_const_k:
if (!(result_type->kind == AST_character_k))
{
type_check_failed = true;
}
break;
case AST_string_const_k:
if (!((result_type->kind == AST_pointer_k) &&
(result_type->type_structure.pointer->pointee_type->kind ==
AST_character_k)))
{
type_check_failed = true;
}
break;
case AST_boolean_const_k:
if (!(result_type->kind == AST_boolean_k))
{
type_check_failed = true;
}
break;
default:
break;
}
if (type_check_failed == true)
{
log_error (location->lineno, NIDL_CONSTTYPE, NULL);
}
ASTP_free_declarators(declarator);
return return_constant;
}
static void AST_finish_operation_node
(
AST_operation_n_t *operation_node_p
)
{
AST_parameter_n_t *param_p;
ASTP_parameter_count_t param_count;
if ((operation_node_p->result->type->kind == AST_pointer_k) &&
(operation_node_p->result->type->type_structure.pointer->pointee_type->kind != AST_void_k) &&
(operation_node_p->result->type->type_structure.pointer->pointee_type->kind != AST_interface_k) &&
!AST_REF_SET(operation_node_p->result) &&
!AST_UNIQUE_SET(operation_node_p->result))
AST_SET_PTR (operation_node_p->result);
for (param_p = operation_node_p->parameters,
param_count.in_params= 0, param_count.out_params=0;
param_p != (AST_parameter_n_t *) NULL;
param_p = param_p->next)
{
param_p->uplink = operation_node_p;
AST_synthesize_param_to_oper_attr(param_p, operation_node_p,
¶m_count);
}
AST_set_oper_has_ins_outs(operation_node_p, ¶m_count);
return;
}
AST_operation_n_t *AST_function_node
(
parser_location_p location,
AST_type_n_t *result_type,
NAMETABLE_id_t op_name,
AST_parameter_n_t *parameters
)
{
AST_operation_n_t *operation_node_p;
operation_node_p = AST_create_operation_node(location, op_name, parameters);
operation_node_p->result = AST_parameter_node (location, operation_node_p->name);
(operation_node_p->result)->type = result_type;
(operation_node_p->result)->uplink = operation_node_p;
if (AST_REF_SET(result_type)) AST_SET_REF(operation_node_p->result);
if (AST_PTR_SET(result_type)) AST_SET_PTR(operation_node_p->result);
if (AST_UNIQUE_SET(result_type)) AST_SET_UNIQUE(operation_node_p->result);
AST_finish_operation_node(operation_node_p);
return operation_node_p;
}
AST_include_n_t *AST_include_node
(
parser_location_p location,
STRTAB_str_t include_file,
STRTAB_str_t include_file_name
)
{
AST_include_n_t *include_node_ptr;
include_node_ptr = NEW (AST_include_n_t);
include_node_ptr->file_name = include_file;
include_node_ptr->simple_file_name = include_file_name;
ASTP_set_fe_info (location, &include_node_ptr->fe_info, fe_include_n_k);
return include_node_ptr;
}
AST_import_n_t *AST_import_node
(
parser_location_p location,
STRTAB_str_t imported_file
)
{
AST_import_n_t *import_node_ptr;
import_node_ptr = NEW (AST_import_n_t);
import_node_ptr->file_name = imported_file;
ASTP_set_fe_info (location, &import_node_ptr->fe_info, fe_import_n_k);
return import_node_ptr;
}
AST_exception_n_t *AST_exception_node
(
parser_location_p location,
NAMETABLE_id_t excep_name
)
{
ASTP_node_t *binding;
AST_exception_n_t *excep_node_ptr;
binding = (ASTP_node_t *)NAMETABLE_lookup_binding(excep_name);
if (binding != NULL)
{
char const *identifier;
NAMETABLE_id_to_string(excep_name, &identifier);
if ((binding->fe_info != (fe_info_t *)NULL) &&
(binding->fe_info->source_line != 0) &&
(binding->fe_info->file != STRTAB_NULL_STR))
{
char const *filename;
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 NULL;
}
excep_node_ptr = NEW (AST_exception_n_t);
excep_node_ptr->name = excep_name;
ASTP_set_fe_info (location, &excep_node_ptr->fe_info, fe_exception_n_k);
NAMETABLE_add_binding(excep_name, (char *)excep_node_ptr);
return excep_node_ptr;
}
AST_name_n_t *AST_name_node
(
NAMETABLE_id_t name
)
{
AST_name_n_t *name_node_ptr;
name_node_ptr = NEW (AST_name_n_t);
name_node_ptr->name = name;
return name_node_ptr;
}
void AST_init
(
parser_location_p location
)
{
zero_constant_p = AST_integer_constant (location, 0L);
ASTP_tagged_union_id = NAMETABLE_add_id ("tagged_union");
ASTP_char_ptr = AST_type_node(location, AST_character_k);
ASTP_boolean_ptr = AST_type_node(location, AST_boolean_k);
ASTP_byte_ptr = AST_type_node(location, AST_byte_k);
ASTP_void_ptr = AST_type_node(location, AST_void_k);
ASTP_handle_ptr = AST_type_node(location, AST_handle_k);
ASTP_short_float_ptr = AST_type_node(location, AST_short_float_k);
ASTP_long_float_ptr = AST_type_node(location, AST_long_float_k);
ASTP_small_int_ptr = AST_type_node(location, AST_small_integer_k);
ASTP_short_int_ptr = AST_type_node(location, AST_short_integer_k);
ASTP_long_int_ptr = AST_type_node(location, AST_long_integer_k);
ASTP_hyper_int_ptr = AST_type_node(location, AST_hyper_integer_k);
ASTP_small_unsigned_ptr = AST_type_node(location, AST_small_unsigned_k);
ASTP_short_unsigned_ptr = AST_type_node(location, AST_short_unsigned_k);
ASTP_long_unsigned_ptr = AST_type_node(location, AST_long_unsigned_k);
ASTP_hyper_unsigned_ptr = AST_type_node(location, AST_hyper_unsigned_k);
return;
}
AST_constant_n_t *AST_integer_constant
(
parser_location_p location,
long int value
)
{
AST_constant_n_t *constant_node_p;
constant_node_p = AST_constant_node (location, AST_int_const_k);
constant_node_p->value.int_val = value;
constant_node_p->fe_info->fe_type_id = fe_const_info;
constant_node_p->fe_info->type_specific.const_kind = fe_int_const_k;
return constant_node_p;
}
AST_interface_n_t *AST_interface_node
(
parser_location_p location
)
{
AST_interface_n_t *interface_node_p;
interface_node_p = NEW (AST_interface_n_t);
ASTP_set_fe_info (location, &interface_node_p->fe_info, fe_interface_n_k);
ASTP_CLR_IF_AF(interface_node_p);
interface_node_p->name = NAMETABLE_NIL_ID;
interface_node_p->implicit_handle_name = NAMETABLE_NIL_ID;
return interface_node_p;
}
AST_type_n_t *AST_lookup_integer_type_node
(
AST_type_k_t int_size,
int int_signed
)
{
AST_type_n_t *type_node_p = NULL;
if (int_signed)
type_node_p = AST_lookup_type_node ((AST_type_k_t)int_size);
else
switch (int_size)
{
case AST_small_integer_k:
type_node_p = AST_lookup_type_node (AST_small_unsigned_k);
break;
case AST_short_integer_k:
type_node_p = AST_lookup_type_node (AST_short_unsigned_k);
break;
case AST_long_integer_k:
type_node_p = AST_lookup_type_node (AST_long_unsigned_k);
break;
case AST_hyper_integer_k:
type_node_p = AST_lookup_type_node (AST_hyper_unsigned_k);
break;
default:
printf("Unexpected type!!!!!\n");
}
return type_node_p;
}
AST_type_n_t *AST_lookup_named_type
(
parser_location_p location,
NAMETABLE_id_t type_name
)
{
AST_type_n_t *type_node_ptr;
type_node_ptr =
(AST_type_n_t *) ASTP_lookup_binding(location,
type_name, fe_type_n_k, TRUE);
if (type_node_ptr == NULL)
{
type_node_ptr = ASTP_long_int_ptr;
}
return type_node_ptr;
}
AST_type_n_t *AST_lookup_type_node
(
AST_type_k_t kind
)
{
AST_type_n_t *type_node_ptr = NULL;
switch (kind)
{
case AST_boolean_k:
type_node_ptr = ASTP_boolean_ptr;
break;
case AST_byte_k:
type_node_ptr = ASTP_byte_ptr;
break;
case AST_character_k:
type_node_ptr = ASTP_char_ptr;
break;
case AST_small_integer_k:
type_node_ptr = ASTP_small_int_ptr;
break;
case AST_small_unsigned_k:
type_node_ptr = ASTP_small_unsigned_ptr;
break;
case AST_short_integer_k:
type_node_ptr = ASTP_short_int_ptr;
break;
case AST_short_unsigned_k:
type_node_ptr = ASTP_short_unsigned_ptr;
break;
case AST_long_integer_k:
type_node_ptr = ASTP_long_int_ptr;
break;
case AST_long_unsigned_k:
type_node_ptr = ASTP_long_unsigned_ptr;
break;
case AST_hyper_integer_k:
type_node_ptr = ASTP_hyper_int_ptr;
break;
case AST_hyper_unsigned_k:
type_node_ptr = ASTP_hyper_unsigned_ptr;
break;
case AST_short_float_k:
type_node_ptr = ASTP_short_float_ptr;
break;
case AST_long_float_k:
type_node_ptr = ASTP_long_float_ptr;
if (the_interface)
AST_SET_DOUBLE_USED(the_interface);
break;
case AST_void_k:
type_node_ptr = ASTP_void_ptr;
break;
case AST_handle_k:
type_node_ptr = ASTP_handle_ptr;
break;
default:
break;
}
return type_node_ptr;
}
AST_constant_n_t *AST_named_constant
(
parser_location_p location,
NAMETABLE_id_t const_name
)
{
AST_constant_n_t *named_const_node_p;
named_const_node_p= (AST_constant_n_t *)
ASTP_lookup_binding(location, const_name,
fe_constant_n_k, TRUE);
if (named_const_node_p == NULL)
{
named_const_node_p = zero_constant_p;
}
return named_const_node_p;
}
AST_constant_n_t *AST_null_constant
(
parser_location_p location
)
{
AST_constant_n_t *const_node_ptr;
const_node_ptr = AST_constant_node(location, AST_nil_const_k);
const_node_ptr->value.int_val = 0;
return const_node_ptr;
}
AST_operation_n_t *AST_operation_node
(
parser_location_p location,
AST_type_n_t *base_type,
ASTP_declarator_n_t *declarator,
ASTP_attributes_t *attributes
)
{
AST_operation_n_t *operation_node_p;
AST_type_n_t *result_type;
ASTP_declarator_op_n_t *function_op, *new_last_op;
AST_parameter_n_t *parameters;
NAMETABLE_id_t op_name;
if ((declarator->last_op == NULL) ||
(declarator->last_op->op_kind != AST_function_k))
{
char const *var_name;
NAMETABLE_id_to_string(declarator->name, &var_name);
log_error(location->lineno, NIDL_VARDECLNOSUP, var_name, NULL);
return NULL;
}
function_op = declarator->last_op;
for (new_last_op = declarator->next_op;
((new_last_op != NULL) && (new_last_op->next_op != function_op));
new_last_op = new_last_op->next_op);
declarator->last_op = new_last_op;
if (new_last_op == NULL)
declarator->next_op = NULL;
else
new_last_op->next_op = NULL;
parameters = function_op->op_info.routine_params;
op_name = declarator->name;
operation_node_p = AST_create_operation_node(location, op_name, parameters);
result_type = AST_propagate_type(location,
base_type, declarator, attributes,
(ASTP_node_t *)operation_node_p);
operation_node_p->result = AST_parameter_node (location, operation_node_p->name);
(operation_node_p->result)->type = result_type;
(operation_node_p->result)->uplink = operation_node_p;
if (ASTP_TEST_ATTR(attributes,ASTP_REF))
AST_SET_REF(operation_node_p->result);
if (ASTP_TEST_ATTR(attributes,ASTP_UNIQUE))
AST_SET_UNIQUE(operation_node_p->result);
if (ASTP_TEST_ATTR(attributes,ASTP_PTR))
AST_SET_PTR(operation_node_p->result);
if (ASTP_TEST_ATTR(attributes,ASTP_STRING))
AST_SET_STRING(operation_node_p->result);
if (ASTP_TEST_ATTR(attributes,ASTP_CONTEXT))
AST_SET_CONTEXT(operation_node_p->result);
ASTP_CLR_ATTR(attributes,
(ASTP_STRING|ASTP_CONTEXT|ASTP_REF|ASTP_UNIQUE|ASTP_PTR));
if (AST_REF_SET(result_type)) AST_SET_REF(operation_node_p->result);
if (AST_PTR_SET(result_type)) AST_SET_PTR(operation_node_p->result);
if (AST_UNIQUE_SET(result_type)) AST_SET_UNIQUE(operation_node_p->result);
if (!AST_DEF_AS_TAG_SET(result_type) &&
((result_type->kind == AST_disc_union_k) ||
(result_type->kind == AST_structure_k)) &&
(result_type->name == NAMETABLE_NIL_ID))
{
char const *identifier;
NAMETABLE_id_to_string(operation_node_p->name, &identifier);
log_error(location->lineno, NIDL_ANONTYPE, identifier, NULL);
}
operation_node_p->op_number = the_interface->op_count++;
AST_set_flags(location, &operation_node_p->flags,
(ASTP_node_t *)operation_node_p, attributes);
AST_finish_operation_node(operation_node_p);
ASTP_add_name_binding (location, op_name, operation_node_p);
FREE(function_op);
ASTP_free_declarators(declarator);
return operation_node_p;
}
AST_parameter_n_t * AST_parameter_node
(
parser_location_p location,
NAMETABLE_id_t identifier
)
{
AST_parameter_n_t * parameter_node_ptr;
parameter_node_ptr = NEW (AST_parameter_n_t);
ASTP_set_fe_info (location, ¶meter_node_ptr->fe_info, fe_parameter_n_k);
parameter_node_ptr->name = identifier;
return parameter_node_ptr;
}
void AST_finish_interface_node
(
parser_location_p location,
AST_interface_n_t *interface_node_p
)
{
if (interface_node_p == NULL)
{
interface_node_p = AST_interface_node(location);
}
ASTP_patch_tag_references(location, interface_node_p);
}
AST_rep_as_n_t *AST_represent_as_node
(
parser_location_p location,
NAMETABLE_id_t name
)
{
AST_rep_as_n_t *represent_as_node;
represent_as_node = NEW (AST_rep_as_n_t);
represent_as_node->type_name = name;
represent_as_node->file_name = STRTAB_NULL_STR;
ASTP_set_fe_info (location, &represent_as_node->fe_info, fe_rep_as_n_k);
return represent_as_node;
}
AST_cs_char_n_t *AST_cs_char_node
(
parser_location_p location,
NAMETABLE_id_t name
)
{
AST_cs_char_n_t *cs_char_node;
cs_char_node = NEW (AST_cs_char_n_t);
cs_char_node->type_name = name;
ASTP_set_fe_info (location, &cs_char_node->fe_info, fe_cs_char_n_k);
return cs_char_node;
}
void ASTP_parse_port
(
AST_interface_n_t *interface_p,
STRTAB_str_t port_string
)
{
STRTAB_str_t protocol_id;
STRTAB_str_t endpoint_id;
char protocol_buf[256];
char endpoint_buf[256];
char const *protocol_start;
char *protocol_end;
char *endpoint_start;
char *endpoint_end;
int i;
boolean found = false;
STRTAB_str_to_string(port_string,&protocol_start);
protocol_end = strchr(protocol_start,':');
if (protocol_end == NULL)
{
log_warning(1,NIDL_NOENDPOINT,protocol_start, NULL);
protocol_id = STRTAB_add_string(protocol_start);
endpoint_id = STRTAB_NULL_STR;
}
else {
strncpy(protocol_buf,protocol_start,protocol_end - protocol_start);
protocol_buf[protocol_end - protocol_start] = '\0';
protocol_id = STRTAB_add_string(protocol_buf);
endpoint_start = protocol_end + 1;
if (*endpoint_start == '[')
{
endpoint_start++;
endpoint_end = strchr(endpoint_start,']');
if (endpoint_end == NULL)
{
log_warning(1,NIDL_ENDPOINTSYNTAX,endpoint_start, NULL);
protocol_id = STRTAB_add_string(protocol_start);
endpoint_id = STRTAB_NULL_STR;
}
else
{
strncpy(endpoint_buf,endpoint_start,endpoint_end - endpoint_start);
endpoint_buf[endpoint_end - endpoint_start] = '\0';
endpoint_id = STRTAB_add_string(endpoint_buf);
if (endpoint_buf[0] == '\0')
{
log_warning(1,NIDL_NOENDPOINT,protocol_start, NULL);
}
}
}
else {
endpoint_id = STRTAB_add_string(endpoint_start);
log_warning(1,NIDL_ENDPOINTSYNTAX,endpoint_start, NULL);
}
}
for (i = 0; i < interface_p->number_of_ports; i++)
{
if (interface_p->protocol[i] == protocol_id)
{
found = true;
log_warning(1,NIDL_DUPPROTOCOL,protocol_start, NULL);
}
}
if (!found)
{
interface_p->number_of_ports++;
if (interface_p->number_of_ports == 1)
{
interface_p->protocol = NEW (STRTAB_str_t);
interface_p->endpoints = NEW (STRTAB_str_t);
}
else {
interface_p->protocol =
RENEW (interface_p->protocol, interface_p->number_of_ports);
interface_p->endpoints =
RENEW (interface_p->endpoints, interface_p->number_of_ports);
}
(interface_p->protocol)[i] = protocol_id;
(interface_p->endpoints)[i] = endpoint_id;
}
}
AST_constant_n_t *AST_string_constant
(
parser_location_p location,
STRTAB_str_t value
)
{
AST_constant_n_t *const_node_ptr;
const_node_ptr = AST_constant_node (location, AST_string_const_k);
const_node_ptr->value.string_val = value;
return const_node_ptr;
}
AST_type_n_t *AST_type_node
(
parser_location_p location,
AST_type_k_t kind
)
{
AST_type_n_t *type_node_ptr;
type_node_ptr = NEW (AST_type_n_t);
type_node_ptr->name = NAMETABLE_NIL_ID;
type_node_ptr->kind = kind;
ASTP_set_fe_info (location, &type_node_ptr->fe_info, fe_type_n_k);
type_node_ptr->fe_info->type_specific.clone = NULL;
switch (kind)
{
case AST_boolean_k:
type_node_ptr->ndr_size = NDR_C_BOOLEAN_SIZE;
break;
case AST_byte_k:
type_node_ptr->ndr_size = NDR_C_BYTE_SIZE;
break;
case AST_character_k:
type_node_ptr->ndr_size = NDR_C_CHARACTER_SIZE;
break;
case AST_small_integer_k:
case AST_small_unsigned_k:
type_node_ptr->ndr_size = NDR_C_SMALL_INT_SIZE;
break;
case AST_short_integer_k:
case AST_short_unsigned_k:
case AST_enum_k:
type_node_ptr->ndr_size = NDR_C_SHORT_INT_SIZE;
break;
case AST_long_integer_k:
case AST_long_unsigned_k:
type_node_ptr->ndr_size = NDR_C_LONG_INT_SIZE;
break;
case AST_hyper_integer_k:
case AST_hyper_unsigned_k:
type_node_ptr->ndr_size = NDR_C_HYPER_INT_SIZE;
break;
case AST_short_float_k:
type_node_ptr->ndr_size = NDR_C_SHORT_FLOAT_SIZE;
break;
case AST_long_float_k:
type_node_ptr->ndr_size = NDR_C_LONG_FLOAT_SIZE;
break;
case AST_pointer_k:
type_node_ptr->ndr_size = NDR_C_POINTER_SIZE;
break;
default:
break;
}
type_node_ptr->alignment_size = type_node_ptr->ndr_size;
return type_node_ptr;
}
AST_type_p_n_t *AST_type_ptr_node
(
parser_location_p location
)
{
AST_type_p_n_t *type_p_node;
type_p_node = NEW (AST_type_p_n_t );
ASTP_set_fe_info (location, &type_p_node->fe_info, fe_type_p_n_k);
return type_p_node;
}
AST_export_n_t *AST_types_to_exports
(
parser_location_p location,
AST_type_p_n_t *type_p_list
)
{
AST_export_n_t *export_list = NULL,
*export_node_ptr;
AST_type_p_n_t *type_p;
for (type_p = type_p_list; type_p != (AST_type_p_n_t *) NULL;
type_p = type_p->next)
{
export_node_ptr = AST_export_node(location,
(ASTP_node_t *)type_p->type, AST_type_k);
export_list = (AST_export_n_t *)
AST_concat_element((ASTP_node_t *)export_list,
(ASTP_node_t *)export_node_ptr);
}
ASTP_free_simple_list((ASTP_node_t *)type_p_list);
return export_list;
}
static void AST_set_oper_has_ins_outs
(
AST_operation_n_t *operation_node,
ASTP_parameter_count_t *param_count
)
{
if (param_count->in_params > 0 )
{
if (!((param_count->in_params == 1) &&
(((operation_node->parameters->type->kind == AST_handle_k)
&& !AST_HANDLE_SET(operation_node->parameters->type))
|| ((operation_node->parameters->type->kind == AST_pointer_k)
&& (operation_node->parameters->type->type_structure.pointer
->pointee_type->kind == AST_handle_k)
&& !AST_HANDLE_SET(operation_node->parameters->type->
type_structure.pointer->pointee_type)))))
{
AST_SET_HAS_INS(operation_node);
}
}
if (param_count->out_params > 0)
{
AST_SET_HAS_OUTS(operation_node);
}
if (operation_node->result->type->kind != AST_void_k)
{
AST_SET_OUT(operation_node->result);
AST_SET_HAS_OUTS(operation_node);
}
return;
}
static void AST_synthesize_param_to_oper_attr
(
AST_parameter_n_t *parameter_node,
AST_operation_n_t *operation_node,
ASTP_parameter_count_t *param_count
)
{
AST_type_n_t *param_type;
if ((parameter_node->type->kind == AST_pointer_k) &&
(parameter_node->type->name == NAMETABLE_NIL_ID))
{
param_type = parameter_node->type->type_structure.pointer->pointee_type;
}
else
{
param_type = parameter_node->type;
}
if (AST_IN_SET(parameter_node))
{
if (param_type->kind == AST_pipe_k)
{
AST_SET_HAS_IN_PIPES(operation_node);
}
else
{
param_count->in_params++;
}
}
if (AST_OUT_SET(parameter_node))
{
if (param_type->kind == AST_pipe_k)
{
AST_SET_HAS_OUT_PIPES(operation_node);
}
else
{
param_count->out_params++;
}
}
return;
}
AST_constant_n_t *AST_enum_constant
(
parser_location_p location,
NAMETABLE_id_t identifier,
AST_exp_n_t * exp
)
{
AST_constant_n_t *constant_node_ptr;
constant_node_ptr = AST_constant_node(location, AST_int_const_k);
constant_node_ptr->name = identifier;
constant_node_ptr->fe_info->fe_type_id = fe_const_info;
constant_node_ptr->fe_info->type_specific.const_kind = fe_enum_const_k;
ASTP_add_name_binding (location, identifier, constant_node_ptr);
constant_node_ptr->value.int_val = exp->exp.constant.val.integer;
constant_node_ptr->int_signed = exp->exp.constant.int_signed;
return constant_node_ptr;
}
AST_type_n_t *AST_pipe_node
(
parser_location_p location,
AST_type_n_t *pipe_type
)
{
AST_pipe_n_t *pipe_node_ptr;
AST_type_n_t *type_node_ptr;
pipe_node_ptr = NEW (AST_pipe_n_t);
type_node_ptr = AST_type_node(location, AST_pipe_k);
pipe_node_ptr->base_type = pipe_type;
type_node_ptr->type_structure.pipe = pipe_node_ptr;
ASTP_set_fe_info(location, &pipe_node_ptr->fe_info, fe_pipe_n_k);
return type_node_ptr;
}