#include <assert.h>
#include <string.h>
#include <stdbool.h>
+#include <unistd.h>
#include <limits.h>
#include <libfirm/firm.h>
return new_r_Unknown(irg, mode);
}
-static const char *dbg_retrieve(const dbg_info *dbg, unsigned *line)
+static src_loc_t dbg_retrieve(const dbg_info *dbg)
{
- const source_position_t *pos = (const source_position_t*) dbg;
- if (pos == NULL)
- return NULL;
- if (line != NULL)
- *line = pos->lineno;
- return pos->input_name;
+ source_position_t const *const pos = (source_position_t const*)dbg;
+ if (pos) {
+ return (src_loc_t){ pos->input_name, pos->lineno, pos->colno };
+ } else {
+ return (src_loc_t){ NULL, 0, 0 };
+ }
}
static dbg_info *get_dbg_info(const source_position_t *pos)
}
}
-#define INVALID_TYPE ((ir_type*)-1)
-
enum {
COMPOUND_IS_STRUCT = false,
COMPOUND_IS_UNION = true
type = skip_typeref(type);
if (type->base.firm_type != NULL) {
- assert(type->base.firm_type != INVALID_TYPE);
return type->base.firm_type;
}
type = skip_typeref(type);
if (type->base.firm_type != NULL) {
- assert(type->base.firm_type != INVALID_TYPE);
return type->base.firm_type;
}
static ir_mode *get_ir_mode_storage(type_t *type)
{
- ir_type *irtype = get_ir_type(type);
+ type = skip_typeref(type);
- /* firm doesn't report a mode for arrays somehow... */
- if (is_Array_type(irtype)) {
+ /* Firm doesn't report a mode for arrays and structs/unions. */
+ if (!is_type_scalar(type)) {
return mode_P_data;
}
- ir_mode *mode = get_type_mode(irtype);
+ ir_type *const irtype = get_ir_type(type);
+ ir_mode *const mode = get_type_mode(irtype);
assert(mode != NULL);
return mode;
}
type_t *arg_type = skip_typeref(expression->base.type);
if (!is_type_compound(arg_type)) {
- ir_mode *mode = get_ir_mode_storage(expression->base.type);
- arg_node = create_conv(dbgi, arg_node, mode);
- arg_node = do_strict_conv(dbgi, arg_node);
+ ir_mode *const mode = get_ir_mode_storage(arg_type);
+ arg_node = create_conv(dbgi, arg_node, mode);
+ arg_node = do_strict_conv(dbgi, arg_node);
}
in[n] = arg_node;
}
if (!is_type_void(return_type)) {
- ir_node *resproj = new_Proj(node, mode_T, pn_Call_T_result);
-
- if (is_type_scalar(return_type)) {
- ir_mode *mode = get_ir_mode_storage(return_type);
- result = new_Proj(resproj, mode, 0);
- ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
- result = create_conv(NULL, result, mode_arith);
- } else {
- ir_mode *mode = mode_P_data;
- result = new_Proj(resproj, mode, 0);
- }
+ ir_node *const resproj = new_Proj(node, mode_T, pn_Call_T_result);
+ ir_mode *const mode = get_ir_mode_storage(return_type);
+ result = new_Proj(resproj, mode, 0);
+ ir_mode *const mode_arith = get_ir_mode_arithmetic(return_type);
+ result = create_conv(NULL, result, mode_arith);
}
}
if (from_var != NULL) {
ir_node *const addr = create_symconst(dbgi, from_var->v.entity);
ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
- value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
+ value_node = new_d_Add(dbgi, value_node, base, mode);
}
if (to_var != NULL) {
ir_node *const addr = create_symconst(dbgi, to_var->v.entity);
&& expression->tp_expression != NULL) {
expression_to_firm(expression->tp_expression);
}
- /* strange gnu extensions: sizeof(function) == 1 */
- if (is_type_function(type)) {
- ir_mode *mode = get_ir_mode_storage(type_size_t);
- return new_Const(get_mode_one(mode));
- }
return get_type_size_node(type);
}
ir_node *const in[2] = { true_val, false_val };
type_t *const type = skip_typeref(expression->base.type);
- ir_mode *mode;
- if (is_type_compound(type)) {
- mode = mode_P;
- } else {
- mode = get_ir_mode_arithmetic(type);
- }
+ ir_mode *const mode = get_ir_mode_arithmetic(type);
ir_node *const val = new_d_Phi(dbgi, lengthof(in), in, mode);
return val;
type_qualifiers_t tq = get_type_qualifier(type, true);
if (initializer->kind == INITIALIZER_VALUE) {
- initializer_value_t *initializer_value = &initializer->value;
- dbg_info *dbgi = get_dbg_info(&entity->base.source_position);
- expression_t *value = initializer_value->value;
- type_t *init_type = value->base.type;
- type_t *skipped = skip_typeref(init_type);
+ expression_t * value = initializer->value.value;
+ type_t *const init_type = skip_typeref(value->base.type);
- if (!is_type_scalar(skipped)) {
+ if (!is_type_scalar(init_type)) {
/* skip convs */
while (value->kind == EXPR_UNARY_CAST)
value = value->unary.value;
goto have_initializer;
}
- ir_node *node = expression_to_firm(initializer_value->value);
-
- ir_mode *mode = get_ir_mode_storage(init_type);
+ ir_node * node = expression_to_firm(value);
+ dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
+ ir_mode *const mode = get_ir_mode_storage(init_type);
node = create_conv(dbgi, node, mode);
node = do_strict_conv(dbgi, node);
if (!currently_reachable())
return NULL;
- dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
- type_t *type = current_function_entity->declaration.type;
- ir_type *func_irtype = get_ir_type(type);
-
- ir_node *in[1];
- int in_len;
- if (get_method_n_ress(func_irtype) > 0) {
- ir_type *res_type = get_method_res_type(func_irtype, 0);
-
- if (statement->value != NULL) {
- ir_node *node = expression_to_firm(statement->value);
- if (!is_compound_type(res_type)) {
- type_t *ret_value_type = statement->value->base.type;
- ir_mode *mode = get_ir_mode_storage(ret_value_type);
- node = create_conv(dbgi, node, mode);
- node = do_strict_conv(dbgi, node);
- }
- in[0] = node;
+ dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
+ type_t *const type = skip_typeref(current_function_entity->declaration.type->function.return_type);
+ ir_node * res = statement->value ? expression_to_firm(statement->value) : NULL;
+
+ int in_len;
+ if (!is_type_void(type)) {
+ ir_mode *const mode = get_ir_mode_storage(type);
+ if (res) {
+ res = create_conv(dbgi, res, mode);
+ res = do_strict_conv(dbgi, res);
} else {
- ir_mode *mode;
- if (is_compound_type(res_type)) {
- mode = mode_P_data;
- } else {
- mode = get_type_mode(res_type);
- }
- in[0] = new_Unknown(mode);
+ res = new_Unknown(mode);
}
in_len = 1;
} else {
- /* build return_value for its side effects */
- if (statement->value != NULL) {
- expression_to_firm(statement->value);
- }
in_len = 0;
}
- ir_node *store = get_store();
- ir_node *ret = new_d_Return(dbgi, store, in_len, in);
+ ir_node *const in[1] = { res };
+ ir_node *const store = get_store();
+ ir_node *const ret = new_d_Return(dbgi, store, in_len, in);
ir_node *end_block = get_irg_end_block(current_ir_graph);
add_immBlock_pred(end_block, ret);
if (currently_reachable()) {
type_t *type = skip_typeref(entity->declaration.type);
assert(is_type_function(type));
- const function_type_t *func_type = &type->function;
- const type_t *return_type
- = skip_typeref(func_type->return_type);
+ type_t *const return_type = skip_typeref(type->function.return_type);
ir_node *ret;
if (is_type_void(return_type)) {
ret = new_Return(get_store(), 0, NULL);
} else {
- ir_mode *mode;
- if (is_type_scalar(return_type)) {
- mode = get_ir_mode_storage(func_type->return_type);
- } else {
- mode = mode_P_data;
- }
+ ir_mode *const mode = get_ir_mode_storage(return_type);
ir_node *in[1];
/* ยง5.1.2.2.3 main implicitly returns 0 */
}
}
+static const char *get_cwd(void)
+{
+ static char buf[1024];
+ if (buf[0] == '\0')
+ getcwd(buf, sizeof(buf));
+ return buf;
+}
+
void translation_unit_to_firm(translation_unit_t *unit)
{
+ if (c_mode & _CXX) {
+ be_dwarf_set_source_language(DW_LANG_C_plus_plus);
+ } else if (c_mode & _C99) {
+ be_dwarf_set_source_language(DW_LANG_C99);
+ } else if (c_mode & _C89) {
+ be_dwarf_set_source_language(DW_LANG_C89);
+ } else {
+ be_dwarf_set_source_language(DW_LANG_C);
+ }
+ be_dwarf_set_compilation_directory(get_cwd());
+
/* initialize firm arithmetic */
tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
ir_set_uninitialized_local_variable_func(uninitialized_local_var);