/* debug.c debug info support Copyright (C) 2001 Bill Currie Author: Bill Currie Date: 2001/7/14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include #include "QF/alloc.h" #include "QF/pr_comp.h" #include "tools/qfcc/include/debug.h" #include "tools/qfcc/include/def.h" #include "tools/qfcc/include/defspace.h" #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/emit.h" #include "tools/qfcc/include/expr.h" #include "tools/qfcc/include/qfcc.h" #include "tools/qfcc/include/reloc.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/type.h" #include "tools/qfcc/include/value.h" int lineno_base; static srcline_t *srclines_freelist; static void push_source_file (void) { srcline_t *srcline; ALLOC (16, srcline_t, srclines, srcline); srcline->source_file = pr.source_file; srcline->source_line = pr.source_line; srcline->next = pr.srcline_stack; pr.srcline_stack = srcline; } static void pop_source_file (void) { srcline_t *tmp; if (!pr.srcline_stack) { notice (0, "unbalanced #includes. bug in preprocessor?"); return; } tmp = pr.srcline_stack; pr.srcline_stack = tmp->next; FREE (srclines, tmp); } #define Sys_Error(fmt...) internal_error(0, fmt) void add_source_file (const char *file) { pr.source_file = ReuseString (file); if (!strpool_findstr (pr.comp_file_set, file)) { strpool_addstr (pr.comp_file_set, file); DARRAY_APPEND (&pr.comp_files, save_string (file)); } } void line_info (char *text) { char *p; char *s; const char *str; int line; int flags; p = text; line = strtol (p, &s, 10); p = s; while (isspace ((unsigned char)*p)) p++; if (!*p) error (0, "Unexpected end of file"); str = make_string (p, &s); // grab the filename p = s; while (isspace ((unsigned char) *p)) p++; flags = strtol (p, &s, 10); switch (flags) { case 1: push_source_file (); break; case 2: pop_source_file (); break; } while (*p && *p != '\n') // ignore rest p++; pr.source_line = line - 1; add_source_file (str); } pr_lineno_t * new_lineno (void) { if (pr.num_linenos == pr.linenos_size) { pr.linenos_size += 1024; pr.linenos = realloc (pr.linenos, pr.linenos_size * sizeof (pr_lineno_t)); } memset (&pr.linenos[pr.num_linenos], 0, sizeof (pr_lineno_t)); return &pr.linenos[pr.num_linenos++]; } static void emit_unit_name (def_t *def, void *data, int index) { if (!is_string (def->type)) { internal_error (0, "%s: expected string def", __FUNCTION__); } EMIT_STRING (def->space, D_STRING (def), pr.unit_name); } static void emit_basedir (def_t *def, void *data, int index) { if (!is_string (def->type)) { internal_error (0, "%s: expected string def", __FUNCTION__); } EMIT_STRING (def->space, D_STRING (def), pr.comp_dir); } static void emit_num_files (def_t *def, void *data, int index) { if (!is_integer (def->type)) { internal_error (0, "%s: expected int def", __FUNCTION__); } D_INT (def) = pr.comp_files.size; } static void emit_files_item (def_t *def, void *data, int index) { if (!is_array (def->type) || !is_string (def->type->t.array.type)) { internal_error (0, "%s: expected array of string def", __FUNCTION__); } if ((unsigned) index >= pr.comp_files.size) { internal_error (0, "%s: out of bounds index: %d %zd", __FUNCTION__, index, pr.comp_files.size); } EMIT_STRING (def->space, D_STRING (def), pr.comp_files.a[index]); } static def_t * emit_compunit (const char *modname) { static struct_def_t compunit_struct[] = { {"unit_name", &type_string, emit_unit_name}, {"basedir", &type_string, emit_basedir}, {"num_files", &type_integer, emit_num_files}, {"files", 0, emit_files_item}, {0, 0} }; int count = pr.comp_files.size; pr.unit_name = modname; compunit_struct[3].type = array_type (&type_string, count); return emit_structure (".compile_unit", 's', compunit_struct, 0, &pr, pr.debug_data, sc_static); } void debug_finish_module (const char *modname) { emit_compunit (modname); }