Beispiel #1
0
char fortran_equivalent_tk_types(type_t* t1, type_t* t2)
{
    type_t* r1 = t1;
    if (is_function_type(r1))
    {
        r1 = function_type_get_return_type(r1);
    }
    r1 = fortran_get_rank0_type_internal(r1, /* ignore pointer */ 1);

    type_t* r2 = t2;
    if (is_function_type(r2))
    {
        r2 = function_type_get_return_type(r2);
    }
    r2 = fortran_get_rank0_type_internal(r2, /* ignore pointer */ 1);

    // Preprocess for character types
    if (fortran_is_character_type(r1))
    {
        r1 = get_unqualified_type(array_type_get_element_type(r1));
    }
    if (fortran_is_character_type(r2))
    {
        r2 = get_unqualified_type(array_type_get_element_type(r2));
    }

    return equivalent_types(get_unqualified_type(r1), get_unqualified_type(r2));
}
Beispiel #2
0
/**
 * Check if two function types are compatible.
 */
static bool function_types_compatible(const function_type_t *func1,
                                      const function_type_t *func2)
{
	const type_t* const ret1 = skip_typeref(func1->return_type);
	const type_t* const ret2 = skip_typeref(func2->return_type);
	if (!types_compatible(ret1, ret2))
		return false;

	if (func1->linkage != func2->linkage)
		return false;

	cc_kind_t cc1 = func1->calling_convention;
	if (cc1 == CC_DEFAULT)
		cc1 = default_calling_convention;
	cc_kind_t cc2 = func2->calling_convention;
	if (cc2 == CC_DEFAULT)
		cc2 = default_calling_convention;

	if (cc1 != cc2)
		return false;

	if (func1->variadic != func2->variadic)
		return false;

	/* can parameters be compared? */
	if ((func1->unspecified_parameters && !func1->kr_style_parameters)
			|| (func2->unspecified_parameters && !func2->kr_style_parameters))
		return true;

	/* TODO: handling of unspecified parameters not correct yet */

	/* all argument types must be compatible */
	function_parameter_t *parameter1 = func1->parameters;
	function_parameter_t *parameter2 = func2->parameters;
	for ( ; parameter1 != NULL && parameter2 != NULL;
			parameter1 = parameter1->next, parameter2 = parameter2->next) {
		type_t *parameter1_type = skip_typeref(parameter1->type);
		type_t *parameter2_type = skip_typeref(parameter2->type);

		parameter1_type = get_unqualified_type(parameter1_type);
		parameter2_type = get_unqualified_type(parameter2_type);

		if (!types_compatible(parameter1_type, parameter2_type))
			return false;
	}
	/* same number of arguments? */
	if (parameter1 != NULL || parameter2 != NULL)
		return false;

	return true;
}
LoadVariableExpression* NodeBuilder::load_var(VariableSymbol* var)
{
  Type* rtype = get_unqualified_type(var->get_type());
  if (!is_kind_of<DataType>(rtype)) {
    trash(var);
    SUIF_THROW(SuifException(String("Cannot make a LoadVariableExpression out of ") +
			     to_id_string(var) + " whose type " +
			     to_id_string(rtype) + " is not a data type."));
  }
  return create_load_variable_expression(_suif_env, to<DataType>(rtype), var);
}
LoadExpression* NodeBuilder::load(Expression* addr)
{
  Type* ptype = get_unqualified_type(addr->get_result_type());
  if (!is_kind_of<PointerType>(ptype)) {
    trash(addr);
    SUIF_THROW(SuifException(String("Cannot make a LoadExpression out of ") +
			     to_id_string(addr) + " whose type " +
			     to_id_string(ptype) + " is not a pointer type."));
  }
  Type* btype =
    get_unqualified_type(to<PointerType>(ptype)->get_reference_type());
  if (!is_kind_of<DataType>(btype)) {
    trash(addr);
    SUIF_THROW(SuifException(String("Cannot make a LoadExpression out of ") +
			     to_id_string(addr) + " whose type " +
			     to_id_string(ptype) + " is not a pointer to a DataType."));
  }
  DataType *dtype = to<DataType>(btype);
  return create_load_expression(_suif_env, dtype, addr);
}
Beispiel #5
0
static type_t* adjust_type_for_parameter_type(type_t* orig)
{
    type_t* result = get_unqualified_type(orig);

    if (is_function_type(result))
    {
        result = get_pointer_type(result);
    }
    else if (is_array_type(result))
    {
        result = get_pointer_type(array_type_get_element_type(result));
    }

    return result;
}
/** Decide if the two types are the same modular qualification.
  */
bool NodeBuilder::is_same_type(Type* t1, Type* t2)
{
  return (TypeHelper::is_isomorphic_type(get_unqualified_type(t1),
					 get_unqualified_type(t2)));
}
/** If t is a pointer type (after removing qualification), return the type
  * it points to.
  * Otherwise return 0.
  */
Type* NodeBuilder::get_pointed_to_type(Type* t)
{
  Type* ptype = get_unqualified_type(t);
  if (!is_kind_of<PointerType>(ptype)) return 0;
  return to<PointerType>(ptype)->get_reference_type();
}
Beispiel #8
0
    TL::Symbol new_function_symbol(
            TL::Symbol current_function,
            const std::string& name,
            TL::Type return_type,
            TL::ObjectList<std::string> parameter_names,
            TL::ObjectList<TL::Type> parameter_types)
    {
        if (IS_FORTRAN_LANGUAGE && current_function.is_nested_function())
        {
            // Get the enclosing function
            current_function = current_function.get_scope().get_related_symbol();
        }

        decl_context_t decl_context = current_function.get_scope().get_decl_context();

        ERROR_CONDITION(parameter_names.size() != parameter_types.size(), "Mismatch between names and types", 0);

        decl_context_t function_context;
        if (IS_FORTRAN_LANGUAGE)
        {
            function_context = new_program_unit_context(decl_context);
        }
        else
        {
            function_context = new_function_context(decl_context);
            function_context = new_block_context(function_context);
        }

        // Build the function type
        int num_parameters = 0;
        scope_entry_t** parameter_list = NULL;

        parameter_info_t* p_types = new parameter_info_t[parameter_types.size()];
        parameter_info_t* it_ptypes = &(p_types[0]);
        TL::ObjectList<TL::Type>::iterator type_it = parameter_types.begin();
        for (TL::ObjectList<std::string>::iterator it = parameter_names.begin();
                it != parameter_names.end();
                it++, it_ptypes++, type_it++)
        {
            scope_entry_t* param = new_symbol(function_context, function_context.current_scope, it->c_str());
            param->entity_specs.is_user_declared = 1;
            param->kind = SK_VARIABLE;
            param->locus = make_locus("", 0, 0);

            param->defined = 1;

            param->type_information = get_unqualified_type(type_it->get_internal_type());

            P_LIST_ADD(parameter_list, num_parameters, param);

            it_ptypes->is_ellipsis = 0;
            it_ptypes->nonadjusted_type_info = NULL;
            it_ptypes->type_info = get_indirect_type(param);
        }

        type_t *function_type = get_new_function_type(
                return_type.get_internal_type(),
                p_types,
                parameter_types.size());

        delete[] p_types;

        // Now, we can create the new function symbol
        scope_entry_t* new_function_sym = NULL;
        if (!current_function.get_type().is_template_specialized_type())
        {
            new_function_sym = new_symbol(decl_context, decl_context.current_scope, name.c_str());
            new_function_sym->entity_specs.is_user_declared = 1;
            new_function_sym->kind = SK_FUNCTION;
            new_function_sym->locus = make_locus("", 0, 0);
            new_function_sym->type_information = function_type;
        }
        else
        {
            scope_entry_t* new_template_sym = new_symbol(
                    decl_context, decl_context.current_scope, name.c_str());
            new_template_sym->kind = SK_TEMPLATE;
            new_template_sym->locus = make_locus("", 0, 0);

            new_template_sym->type_information = get_new_template_type(
                    decl_context.template_parameters,
                    function_type,
                    uniquestr(name.c_str()),
                    decl_context, make_locus("", 0, 0));

            template_type_set_related_symbol(new_template_sym->type_information, new_template_sym);

            // The new function is the primary template specialization
            new_function_sym = named_type_get_symbol(
                    template_type_get_primary_type(
                        new_template_sym->type_information));
        }

        function_context.function_scope->related_entry = new_function_sym;
        function_context.block_scope->related_entry = new_function_sym;

        new_function_sym->related_decl_context = function_context;

        new_function_sym->entity_specs.related_symbols = parameter_list;
        new_function_sym->entity_specs.num_related_symbols = num_parameters;
        for (int i = 0; i < new_function_sym->entity_specs.num_related_symbols; ++i)
        {
            symbol_set_as_parameter_of_function(
                    new_function_sym->entity_specs.related_symbols[i], new_function_sym, /* parameter position */ i);
        }

        // Make it static
        new_function_sym->entity_specs.is_static = 1;

        // Make it member if the enclosing function is member
        if (current_function.is_member())
        {
            new_function_sym->entity_specs.is_member = 1;
            new_function_sym->entity_specs.class_type = current_function.get_class_type().get_internal_type();

            new_function_sym->entity_specs.access = AS_PUBLIC;

            ::class_type_add_member(new_function_sym->entity_specs.class_type, new_function_sym);
        }

        if (current_function.is_inline())
            new_function_sym->entity_specs.is_inline = 1;

        // new_function_sym->entity_specs.is_defined_inside_class_specifier =
        //     current_function.get_internal_symbol()->entity_specs.is_defined_inside_class_specifier;

        if (IS_FORTRAN_LANGUAGE && current_function.is_in_module())
        {
            scope_entry_t* module_sym = current_function.in_module().get_internal_symbol();
            new_function_sym->entity_specs.in_module = module_sym;
            P_LIST_ADD(
                    module_sym->entity_specs.related_symbols,
                    module_sym->entity_specs.num_related_symbols,
                    new_function_sym);
            new_function_sym->entity_specs.is_module_procedure = 1;
        }

        return new_function_sym;
    }