translation_unit_t* add_new_file_to_compilation_process(
        compilation_file_process_t* current_file_process,
        const char* file_path,
        const char* output_file,
        compilation_configuration_t* configuration,
        int tag)
{
    ERROR_CONDITION(tag < 0, "Invalid tag", 0);

    translation_unit_t* translation_unit = NEW0(translation_unit_t);
    // Initialize with the translation unit root tree
    translation_unit->input_filename = uniquestr(file_path);

    compilation_file_process_t *new_compiled_file = NEW0(compilation_file_process_t);

    configuration->verbose = CURRENT_CONFIGURATION->verbose;
    configuration->do_not_link = CURRENT_CONFIGURATION->do_not_link;
    configuration->do_not_compile = CURRENT_CONFIGURATION->do_not_compile;
    configuration->do_not_prettyprint = CURRENT_CONFIGURATION->do_not_prettyprint;

    new_compiled_file->translation_unit = translation_unit;
    new_compiled_file->compilation_configuration = configuration;
    new_compiled_file->tag = tag;

    if ((configuration->do_not_link
            || configuration->do_not_compile)
            && output_file != NULL)
    {
        translation_unit->output_filename = uniquestr(output_file);
    }

    // Give a fallback value
    if (configuration->do_not_link
            && configuration->do_not_compile
            && translation_unit->output_filename == NULL)
    {
        translation_unit->output_filename = "-";
    }

    if (current_file_process == NULL)
    {
        P_LIST_ADD(compilation_process.translation_units, 
                compilation_process.num_translation_units, 
                new_compiled_file);
    }
    else
    {
        P_LIST_ADD(current_file_process->secondary_translation_units,
                current_file_process->num_secondary_translation_units,
                new_compiled_file);
    }
    return translation_unit;
}
// Set additional mcxx options
int config_set_options(struct compilation_configuration_tag* config, const char* index, const char* value)
{
    int num;
    const char** blank_separated_options = blank_separate_values(value, &num);

    num++;
    const char** real_options = calloc(num, sizeof(*real_options));

    int i;
    for (i = 1; i < num; i++)
    {
        real_options[i] = blank_separated_options[i - 1];
    }

    // Change the current configuration otherwise we will handle the parameters
    // in the wrong profile
    struct compilation_configuration_tag* previous = CURRENT_CONFIGURATION;
    SET_CURRENT_CONFIGURATION(config);

    real_options[0] = uniquestr("mcxx");

    parse_arguments(num, real_options, /* from_command_line= */ 0, /* parse_implicits_only*/ 0);

    // Restore the original one
    SET_CURRENT_CONFIGURATION(previous);

    return 0;
}
int config_add_preprocessor_prefix(struct compilation_configuration_tag* config, const char* index, const char* value)
{
    const char *reserved[] = {
        "gcc", 
        "mcc",
        "mcxx",
        /* sentinel */ NULL
    };
    
    int i;
    for (i = 0; reserved[i] != NULL; i++)
    {
        if (strcasecmp(value, reserved[i]) == 0)
        {
            fprintf(stderr, "%s is a reserved pragma prefix\n", reserved[i]);
            return 1;
        }
    }
    
    // Reuse P_LIST_ADD
    int num_prefixes = config->num_pragma_custom_prefix;

    P_LIST_ADD(config->pragma_custom_prefix,
            config->num_pragma_custom_prefix,
            uniquestr(value));

    // Allocate pragma directive info
    pragma_directive_set_t* new_info = calloc(1, sizeof(*new_info));

    P_LIST_ADD(config->pragma_custom_prefix_info,
            num_prefixes, new_info);

    return 0;
}
const char* get_unique_name(void)
{
    static int num_var = 100;
    char result[15];

    snprintf(result, 14, "$.anon%05d", num_var);

    return uniquestr(result);
}
Exemple #5
0
tl_type_t tl_string(const char* str)
{
    tl_type_t result;
    
    result.kind = TL_STRING;
    result.data._string = uniquestr(str);

    return result;
}
    std::string Type::get_declaration_with_parameters(Scope sc, const std::string& symbol_name,
            ObjectList<std::string>& parameters, ObjectList<std::string>& parameter_attributes, TypeDeclFlags flags) const
    {
        int num_parameters = this->parameters().size();

        const char** parameter_names  = new const char*[num_parameters + 1];
        const char** param_attributes = new const char*[num_parameters + 1];

        for (int i = 0; i < num_parameters; i++)
        {
            parameter_names[i] = NULL;
            param_attributes[i] = NULL;
        }

        int orig_size = parameters.size();
        for (int i = 0; i < orig_size; i++)
        {
            parameter_names[i] = uniquestr(parameters[i].c_str());
            param_attributes[i] = uniquestr(parameter_attributes[i].c_str());
        }

        const char* result = get_declaration_string(_type_info, sc._decl_context, symbol_name.c_str(),
                "", 0, num_parameters, parameter_names, param_attributes, flags == PARAMETER_DECLARATION);

        for (int i = 0; i < num_parameters; i++)
        {
            if (i < orig_size)
            {
                parameters[i] = parameter_names[i];
            }
            else
            {
                if (parameter_names[i] != NULL)
                    parameters.append(parameter_names[i]);
                else
                    parameters.append("");
            }
        }

        delete[] parameter_names;
        delete[] param_attributes;

        return result;
    }
int config_add_compiler_phase(struct compilation_configuration_tag* config, const char* index, const char* value)
{
	compiler_phase_loader_t* cl = calloc(1, sizeof(*cl));
	cl->func = compiler_phase_loader;
	cl->data = (void*)uniquestr(value);

    P_LIST_ADD(config->phase_loader, 
            config->num_compiler_phases,
			cl);

    return 0;
}
const char* strappend(const char* orig, const char* appended)
{
    int total = strlen(orig) + strlen(appended) + 1;

    char append_tmp[total];
    append_tmp[0] = '\0';

    strcat(append_tmp, orig);
    strcat(append_tmp, appended);

    return uniquestr(append_tmp);
}
Exemple #9
0
// Very minimal html stripping, DO NOT RELY ON IT FOR CRITICAL MISSIONS
static const char* mini_strip_html(const char* c)
{
    if (c == NULL)
        return "";

    int size = strlen(c);
    if (size == 0)
        return "";

    char output[size * 2];

    const char *p = c;
    char *q = output;

    while (*p != '\0')
    {
        if (q >= &output[size * 2])
            internal_error("string is too large for protection", 0);

        // We only remove < and > but for sure there are many others to be
        // removed
        if (*p == '<')
        {
            if ((q + 3) >= &output[size * 2])
                internal_error("string is too large for protection", 0);

            *q = '&'; q++;
            *q = 'l'; q++;
            *q = 't'; q++;
            *q = ';'; q++;
        }
        else if (*p == '>')
        {
            if ((q + 3) >= &output[size * 2])
                internal_error("string is too large for protection", 0);

            *q = '&'; q++;
            *q = 'g'; q++;
            *q = 't'; q++;
            *q = ';'; q++;
        }
        else
        {
            *q = *p; q++;
        }
        p++;
    }
    *q = '\0';

    return uniquestr(output);
}
const char* strtolower(const char* c)
{
    if (c != NULL)
    {
        int n = strlen(c);
        char result[n + 1];
        int i;
        for (i = 0; i < n; i++)
        {
            result[i] = tolower(c[i]);
        }
        result[n] = '\0';
        return uniquestr(result);
    }
    return NULL;
}
Exemple #11
0
void* extensible_struct_get_field(extensible_struct_t* extensible_struct, 
        const char* field_name)
{
    if (extensible_struct->hash == NULL)
        return NULL;

    rb_red_blk_node* n = rb_tree_query(extensible_struct->hash, uniquestr(field_name));
    if (n != NULL)
    {
        return rb_node_get_info(n);
    }
    else
    {
        return NULL;
    }
}
Exemple #12
0
compilation_configuration_t* new_compilation_configuration(
        const char* name,
        compilation_configuration_t* base)
{
    compilation_configuration_t* result = xcalloc(1, sizeof(*result));

    result->configuration_name = uniquestr(name);
    result->base_configuration = base;

    // Default target tools
    result->target_objcopy = TARGET_OBJCOPY;
    result->target_objdump = TARGET_OBJDUMP;
    result->target_ar = TARGET_AR;

    // Fortran default column widths
    result->input_column_width = 72;
    result->output_column_width = 132;

    return result;
}
Exemple #13
0
const char* fortran_print_type_str(type_t* t)
{
    t = no_ref(t);

    if (is_error_type(t))
    {
        return "<error-type>";
    }

    if (is_hollerith_type(t))
    {
        return "HOLLERITH";
    }

    const char* result = "";
    char is_pointer = 0;
    if (is_pointer_type(t))
    {
        is_pointer = 1;
        t = pointer_type_get_pointee_type(t);
    }

    struct array_spec_tag {
        nodecl_t lower;
        nodecl_t upper;
        char is_undefined;
    } array_spec_list[MCXX_MAX_ARRAY_SPECIFIER] = { { nodecl_null(), nodecl_null(), 0 }  };

    int array_spec_idx;
    for (array_spec_idx = MCXX_MAX_ARRAY_SPECIFIER - 1; 
            fortran_is_array_type(t);
            array_spec_idx--)
    {
        if (array_spec_idx < 0)
        {
            internal_error("too many array dimensions %d\n", MCXX_MAX_ARRAY_SPECIFIER);
        }

        if (!array_type_is_unknown_size(t))
        {
            array_spec_list[array_spec_idx].lower = array_type_get_array_lower_bound(t);
            array_spec_list[array_spec_idx].upper = array_type_get_array_upper_bound(t);
        }
        else
        {
            array_spec_list[array_spec_idx].is_undefined = 1;
        }

        t = array_type_get_element_type(t);
    }

    char is_array = (array_spec_idx != (MCXX_MAX_ARRAY_SPECIFIER - 1));

    if (is_bool_type(t)
            || is_integer_type(t)
            || is_floating_type(t)
            || is_double_type(t)
            || is_complex_type(t))
    {
        const char* type_name = NULL;
        char c[128] = { 0 };

        if (is_bool_type(t))
        {
            type_name = "LOGICAL";
        }
        else if (is_integer_type(t))
        {
            type_name = "INTEGER";
        }
        else if (is_floating_type(t))
        {
            type_name = "REAL";
        }
        else if (is_complex_type(t))
        {
            type_name = "COMPLEX";
        }
        else
        {
            internal_error("unreachable code", 0);
        }

        size_t size = type_get_size(t);
        if (is_floating_type(t))
        {
            // KIND of floats is their size in byes (using the bits as in IEEE754) 
            size = (floating_type_get_info(t)->bits) / 8;
        }
        else if (is_complex_type(t))
        {
            // KIND of a complex is the KIND of its component type
            type_t* f = complex_type_get_base_type(t);
            size = (floating_type_get_info(f)->bits) / 8;
        }

        snprintf(c, 127, "%s(%zd)", type_name, size);
        c[127] = '\0';

        result = uniquestr(c);
    }
    else if (is_class_type(t))
    {
        scope_entry_t* entry = named_type_get_symbol(t);
        char c[128] = { 0 };
        snprintf(c, 127, "TYPE(%s)", 
                entry->symbol_name);
        c[127] = '\0';

        result = uniquestr(c);
    }
    else if (fortran_is_character_type(t))
    {
        nodecl_t length = array_type_get_array_size_expr(t);
        char c[128] = { 0 };
        snprintf(c, 127, "CHARACTER(LEN=%s)",
                nodecl_is_null(length) ? "*" : codegen_to_str(length, nodecl_retrieve_context(length)));
        c[127] = '\0';
        result = uniquestr(c);
    }
    else if (is_function_type(t))
    {
        result = "PROCEDURE";
    }
    else
    {
        const char* non_printable = NULL;
        uniquestr_sprintf(&non_printable, "non-fortran type '%s'", print_declarator(t));
        return non_printable;
    }

    if (is_pointer)
    {
        result = strappend(result, ", POINTER");
    }

    if (is_array)
    {
        array_spec_idx++;
        result = strappend(result, ", DIMENSION(");

        while (array_spec_idx <= (MCXX_MAX_ARRAY_SPECIFIER - 1))
        {
            if (!array_spec_list[array_spec_idx].is_undefined)
            {
                result = strappend(result, codegen_to_str(array_spec_list[array_spec_idx].lower, 
                            nodecl_retrieve_context(array_spec_list[array_spec_idx].lower)));
                result = strappend(result, ":");
                result = strappend(result, codegen_to_str(array_spec_list[array_spec_idx].upper, 
                            nodecl_retrieve_context(array_spec_list[array_spec_idx].upper)));
            }
            else
            {
                result = strappend(result, ":");
            }
            if ((array_spec_idx + 1) <= (MCXX_MAX_ARRAY_SPECIFIER - 1))
            {
                result = strappend(result, ", ");
            }
            array_spec_idx++;
        }

        result = strappend(result, ")");
    }

    return result;
}
// Set linker name
int config_set_linker_name(struct compilation_configuration_tag* config, const char* index, const char* value)
{
    config->linker_name = uniquestr(value);
    return 0;
}
Exemple #15
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;
    }
    Symbol Overload::solve(
            ObjectList<Symbol> candidate_functions,
            Type implicit_argument_type,
            ObjectList<Type> argument_types, 
            const std::string filename,
            int line,
            bool &valid, 
            ObjectList<Symbol>& viable_functions,
            ObjectList<Symbol>& argument_conversor)
    {
        valid = false;

        // Try hard to not to do useless work
        if (candidate_functions.empty())
        {
            return Symbol(NULL);
        }

        scope_entry_list_t* first_candidate_list = NULL;
        
        // Build the candidates list
        for (ObjectList<Symbol>::iterator it = candidate_functions.begin();
                it != candidate_functions.end();
                it++)
        {
            Symbol sym(*it);
            first_candidate_list = entry_list_add(first_candidate_list, sym.get_internal_symbol());
        }

        // Build the type array
        unsigned int i = argument_types.size();
        type_t** argument_types_array = new type_t*[argument_types.size() + 1];
        argument_types_array[0] = implicit_argument_type.get_internal_type();
        for (i = 0; i < argument_types.size(); i++)
        {
            argument_types_array[i+1] = argument_types[i].get_internal_type();
        }

        // Now we need a decl_context_t but we were not given any explicitly,
        // use the one of the first candidate
        decl_context_t decl_context = candidate_functions[0].get_scope().get_decl_context();

        // Unfold and mix!
        scope_entry_list_t* candidate_list = NULL;
        candidate_list = unfold_and_mix_candidate_functions(first_candidate_list,
                NULL /* builtins */,
                &argument_types_array[1], argument_types.size(),
                decl_context,
                uniquestr(filename.c_str()), line,
                NULL /* explicit template arguments */);

        {
            ObjectList<Symbol> list;
            Scope::convert_to_vector(candidate_list, list);
            viable_functions.append(list);
        }

        candidate_t* candidate_set = NULL;

        scope_entry_list_iterator_t* it = NULL;
        for (it = entry_list_iterator_begin(candidate_list);
                !entry_list_iterator_end(it);
                entry_list_iterator_next(it))
        {
            scope_entry_t* entry = entry_list_iterator_current(it);
            if (entry->entity_specs.is_member)
            {
                candidate_set = add_to_candidate_set(candidate_set,
                        entry,
                        argument_types.size() + 1,
                        argument_types_array);
            }
            else
            {
                candidate_set = add_to_candidate_set(candidate_set,
                        entry,
                        argument_types.size(),
                        argument_types_array + 1);
            }
        }
        entry_list_iterator_free(it);

        // We also need a scope_entry_t** for holding the conversor argument
        scope_entry_t** conversor_per_argument = new scope_entry_t*[argument_types.size() + 1];

        // Now invoke all the machinery
        scope_entry_t* entry_result =
        solve_overload(candidate_set,
                decl_context,
                uniquestr(filename.c_str()), line,
                conversor_per_argument);

        if (entry_result != NULL)
        {
            valid = true;
            // Store the arguments
            argument_conversor.clear();
            for (i = 0; i < argument_types.size(); i++)
            {
                argument_conversor.append(Symbol(conversor_per_argument[i]));
            }
        }

        // Free the conversor per argument
        delete[] conversor_per_argument;

        // Free the type array
        delete[] argument_types_array;

        // Free the scope entry list
        free_scope_entry_list(candidate_list);

        // This one has been allocated above
        free_scope_entry_list(first_candidate_list);

        return Symbol(entry_result);
    }
Exemple #17
0
void extensible_struct_set_field(extensible_struct_t* extensible_struct, 
        const char* field_name,
        void *data)
{
    rb_tree_insert(extensible_struct->hash, uniquestr(field_name), data);
}
Exemple #18
0
 void Symbol::set_name(std::string name)
 {
     _symbol->symbol_name = uniquestr(name.c_str());
 }
Exemple #19
0
int config_set_fortran_preprocessor_name(struct compilation_configuration_tag* config, const char* index, const char* value)
{
    config->fortran_preprocessor_name = uniquestr(value);
    return 0;
}