Add the column to the debug information.
[libfirm] / ir / be / bedwarf.c
index a529f7f..5c7fa64 100644 (file)
@@ -432,6 +432,9 @@ typedef struct dwarf_t {
        unsigned                 last_line;
 } dwarf_t;
 
+static dwarf_source_language language;
+static const char           *comp_dir;
+
 static unsigned insert_file(dwarf_t *env, const char *filename)
 {
        unsigned num;
@@ -634,21 +637,15 @@ static void emit_pubnames(dwarf_t *env)
 
 static void dwarf_set_dbg_info(dbg_handle *h, dbg_info *dbgi)
 {
-       dwarf_t *env = (dwarf_t*) h;
-       const char *filename;
-       unsigned    lineno;
-       unsigned    column = 0;
-       unsigned    filenum;
-
-       if (dbgi == NULL)
-               return;
+       dwarf_t  *const env = (dwarf_t*)h;
+       src_loc_t const loc = ir_retrieve_dbg_info(dbgi);
+       unsigned        filenum;
 
-       filename = ir_retrieve_dbg_info(dbgi, &lineno);
-       if (filename == NULL)
+       if (!loc.file)
                return;
-       filenum = insert_file(env, filename);
 
-       be_emit_irprintf("\t.loc %u %u %u\n", filenum, lineno, column);
+       filenum = insert_file(env, loc.file);
+       be_emit_irprintf("\t.loc %u %u %u\n", filenum, loc.line, loc.column);
        be_emit_write_line();
 }
 
@@ -671,25 +668,10 @@ static void emit_entity_label(const ir_entity *entity)
  */
 static void emit_dbginfo(dwarf_t *env, const dbg_info *dbgi)
 {
-       const char *filename;
-       unsigned line;
-       unsigned file;
-
-       if (dbgi == NULL) {
-               emit_uleb128(0);
-               emit_uleb128(0);
-               return;
-       }
-       filename = ir_retrieve_dbg_info(dbgi, &line);
-       if (filename == NULL) {
-               emit_uleb128(0);
-               emit_uleb128(0);
-               return;
-       }
-
-       file = insert_file(env, filename);
+       src_loc_t const loc  = ir_retrieve_dbg_info(dbgi);
+       unsigned  const file = loc.file ? insert_file(env, loc.file) : 0;
        emit_uleb128(file);
-       emit_uleb128(line);
+       emit_uleb128(loc.line);
 }
 
 static void emit_subprogram_abbrev(void)
@@ -877,6 +859,12 @@ static void emit_compound_type_abbrev(void)
        //register_attribute(DW_AT_decl_line,  DW_FORM_udata);
        end_abbrev();
 
+       begin_abbrev(DW_TAG_class_type, DW_TAG_class_type, DW_CHILDREN_yes);
+       register_attribute(DW_AT_byte_size,  DW_FORM_udata);
+       //register_attribute(DW_AT_decl_file,  DW_FORM_udata);
+       //register_attribute(DW_AT_decl_line,  DW_FORM_udata);
+       end_abbrev();
+
        begin_abbrev(DW_TAG_member, DW_TAG_member, DW_CHILDREN_no);
        register_attribute(DW_AT_type,                 DW_FORM_ref4);
        register_attribute(DW_AT_name,                 DW_FORM_string);
@@ -920,11 +908,13 @@ static void emit_compound_type(dwarf_t *env, const ir_type *type)
        }
 
        emit_type_label(type);
-       if (is_Union_type(type)) {
+       if (is_Struct_type(type)) {
+               emit_uleb128(DW_TAG_structure_type);
+       } else if (is_Union_type(type)) {
                emit_uleb128(DW_TAG_union_type);
        } else {
-               assert(is_Struct_type(type));
-               emit_uleb128(DW_TAG_structure_type);
+               assert(is_Class_type(type));
+               emit_uleb128(DW_TAG_class_type);
        }
        emit_uleb128(get_type_size_bytes(type));
        for (i = 0; i < n_members; ++i) {
@@ -1021,6 +1011,7 @@ static void emit_type(dwarf_t *env, ir_type *type)
        case tpo_primitive: emit_base_type(type);            break;
        case tpo_pointer:   emit_pointer_type(env, type);    break;
        case tpo_array:     emit_array_type(env, type);      break;
+       case tpo_class:
        case tpo_struct:
        case tpo_union:     emit_compound_type(env, type);   break;
        case tpo_method:    emit_subroutine_type(env, type); break;
@@ -1081,7 +1072,10 @@ static void emit_compile_unit_abbrev(void)
        register_attribute(DW_AT_stmt_list, DW_FORM_data4);
        register_attribute(DW_AT_producer,  DW_FORM_string);
        register_attribute(DW_AT_name,      DW_FORM_string);
-       register_attribute(DW_AT_comp_dir,  DW_FORM_string);
+       if (language != 0)
+               register_attribute(DW_AT_language,  DW_FORM_data2);
+       if (comp_dir != NULL)
+               register_attribute(DW_AT_comp_dir,  DW_FORM_string);
        end_abbrev();
 }
 
@@ -1130,7 +1124,10 @@ static void dwarf_unit_begin(dbg_handle *handle, const char *filename)
                           ir_get_version_minor(),
                           ir_get_version_revision());
        emit_string(filename);
-       emit_string("/foo/bar/");
+       if (language != 0)
+               emit_int16(DW_LANG_C_plus_plus);
+       if (comp_dir != NULL)
+               emit_string(comp_dir);
 }
 
 static void dwarf_unit_end(dbg_handle *handle)
@@ -1193,3 +1190,13 @@ void be_init_dwarf(void)
 {
        be_register_dbgout_module("dwarf", be_dwarf_open);
 }
+
+void be_dwarf_set_source_language(dwarf_source_language new_language)
+{
+       language = new_language;
+}
+
+void be_dwarf_set_compilation_directory(const char *new_comp_dir)
+{
+       comp_dir = new_comp_dir;
+}