global_symbols[i].is_variadic = 0;
global_symbols[i].is_implicit = 0;
global_symbols[i].extern_emitted = 0;
+ global_symbols[i].is_static = 0;
+ global_symbols[i].used = 0;
+ global_symbols[i].decl_line = 0;
+
+ if (global_symbols[i].decl_filename) {
+
+ free (global_symbols[i].decl_filename);
+ global_symbols[i].decl_filename = 0;
+
+ }
+
+ if (global_symbols[i].decl_start) {
+
+ free (global_symbols[i].decl_start);
+ global_symbols[i].decl_start = 0;
+
+ }
+
+ global_symbols[i].decl_caret_offset = 0;
if (global_symbols[i].tag_name) {
global_symbols[global_symbol_count].is_variadic = 0;
global_symbols[global_symbol_count].is_implicit = 0;
global_symbols[global_symbol_count].extern_emitted = 0;
+ global_symbols[global_symbol_count].is_static = 0;
+ global_symbols[global_symbol_count].used = 0;
+ global_symbols[global_symbol_count].decl_line = lineno;
+ global_symbols[global_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ global_symbols[global_symbol_count].decl_start = line_start ? xstrdup (line_start) : 0;
+ global_symbols[global_symbol_count].decl_caret_offset = (line_start && name_caret) ? (long) (name_caret - line_start) : 0;
global_symbols[global_symbol_count].tag_name = 0;
global_symbol_count++;
}
+ if (local_symbols[i].decl_filename) {
+
+ free (local_symbols[i].decl_filename);
+ local_symbols[i].decl_filename = 0;
+
+ }
+
+ if (local_symbols[i].decl_start) {
+
+ free (local_symbols[i].decl_start);
+ local_symbols[i].decl_start = 0;
+
+ }
+
if (local_symbols[i].pointed_tag_name) {
free (local_symbols[i].pointed_tag_name);
}
+ if (local_symbols[i].decl_filename) {
+
+ free (local_symbols[i].decl_filename);
+ local_symbols[i].decl_filename = 0;
+
+ }
+
+ if (local_symbols[i].decl_start) {
+
+ free (local_symbols[i].decl_start);
+ local_symbols[i].decl_start = 0;
+
+ }
+
if (local_symbols[i].pointed_tag_name) {
free (local_symbols[i].pointed_tag_name);
local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = line;
+ local_symbols[local_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ local_symbols[local_symbol_count].decl_start = start ? xstrdup (start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = (start && caret && caret >= start) ? (long) (caret - start) : 0;
local_symbol_count++;
current_local_stack_size = new_size;
local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = line;
+ local_symbols[local_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ local_symbols[local_symbol_count].decl_start = start ? xstrdup (start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = (start && caret && caret >= start) ? (long) (caret - start) : 0;
local_symbol_count++;
static void set_local_symbol_array (const char *name, int is_array) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->is_array = is_array ? 1 : 0;
static void set_local_symbol_array_element_size (const char *name, int elem_size) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->array_element_size = elem_size > 0 ? elem_size : 0;
static void set_local_symbol_array_dimensions (const char *name, int dims) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->array_dimensions = dims > 0 ? dims : 0;
static void set_local_symbol_pointer_info (const char *name, int pointer_depth, int pointed_size) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (pointer_depth > 0 && parsed_type_is_aggregate && parsed_type_size > (DATA_PTR & 0x1f) && pointed_size <= (DATA_PTR & 0x1f)) {
pointed_size = parsed_type_size;
local_symbols[local_symbol_count].pointed_size = pending_params[i].pointed_size;
local_symbols[local_symbol_count].pointed_tag_name = pending_params[i].pointed_tag_name ? xstrdup (pending_params[i].pointed_tag_name) : 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = pending_params[i].decl_line;
+ local_symbols[local_symbol_count].decl_filename = pending_params[i].decl_filename ? xstrdup (pending_params[i].decl_filename) : 0;
+ local_symbols[local_symbol_count].decl_start = pending_params[i].decl_start ? xstrdup (pending_params[i].decl_start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = pending_params[i].decl_caret_offset;
local_symbol_count++;
slot_size = pending_params[i].size;
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
statement_ends_control_flow = block_ends_control_flow;
current_parse_block_depth--;
+ warn_unused_local_symbols (block_local_start, get_filename ());
truncate_local_symbols (block_local_start, block_stack_start);
}
*/
if (tok.kind != TOK_LPAREN && (name_is_function_designator || (find_global_symbol (name) >= 0 && get_global_symbol_kind (name) == GLOBAL_SYMBOL_FUNCTION))) {
+ {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0 && global_symbols[function_symbol_index].kind == GLOBAL_SYMBOL_FUNCTION) {
+ global_symbols[function_symbol_index].used = 1;
+ }
+
+ }
+
emit_load_address_to_reg_now (reg, name);
set_rhs_last_pointer_info (1, DATA_NONE);
return;
}
+ {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0 && global_symbols[function_symbol_index].kind == GLOBAL_SYMBOL_FUNCTION) {
+ global_symbols[function_symbol_index].used = 1;
+ }
+
+ }
+
inline_index = find_inline_function (name);
if (inline_index >= 0 &&
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
}
+ warn_unused_local_symbols (for_scope_start, get_filename ());
+
truncate_local_symbols (for_scope_start, for_stack_start);
statement_ends_control_flow = condition_is_infinite && !loop_escape_seen;
should_emit = add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 0, last_declarator_name_start, last_declarator_name_caret, last_declarator_name_line);
+ if (should_emit) {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0) {
+ global_symbols[function_symbol_index].is_static = (storage_class == STORAGE_STATIC);
+ }
+
+ }
+
set_global_symbol_size (name, return_is_void ? DATA_VOID : return_size);
set_global_symbol_unsigned (name, 0);
set_global_symbol_floating (name, return_is_floating);
}
+ warn_unused_local_symbols (0, function_filename_copy ? function_filename_copy : get_filename ());
+
reset_local_symbols ();
reset_goto_labels ();
masm_flush_data_line ();
}
+ warn_unused_static_functions (get_filename ());
emit_pending_extern_symbols ();
if (vec_dllexports.length || vec_dllaliases.length) {
global_symbols[i].is_variadic = 0;
global_symbols[i].is_implicit = 0;
global_symbols[i].extern_emitted = 0;
+ global_symbols[i].is_static = 0;
+ global_symbols[i].used = 0;
+ global_symbols[i].decl_line = 0;
+
+ if (global_symbols[i].decl_filename) {
+
+ free (global_symbols[i].decl_filename);
+ global_symbols[i].decl_filename = 0;
+
+ }
+
+ if (global_symbols[i].decl_start) {
+
+ free (global_symbols[i].decl_start);
+ global_symbols[i].decl_start = 0;
+
+ }
+
+ global_symbols[i].decl_caret_offset = 0;
if (global_symbols[i].tag_name) {
global_symbols[global_symbol_count].is_variadic = 0;
global_symbols[global_symbol_count].is_implicit = 0;
global_symbols[global_symbol_count].extern_emitted = 0;
+ global_symbols[global_symbol_count].is_static = 0;
+ global_symbols[global_symbol_count].used = 0;
+ global_symbols[global_symbol_count].decl_line = lineno;
+ global_symbols[global_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ global_symbols[global_symbol_count].decl_start = line_start ? xstrdup (line_start) : 0;
+ global_symbols[global_symbol_count].decl_caret_offset = (line_start && name_caret) ? (long) (name_caret - line_start) : 0;
global_symbols[global_symbol_count].tag_name = 0;
global_symbol_count++;
}
+ if (local_symbols[i].decl_filename) {
+
+ free (local_symbols[i].decl_filename);
+ local_symbols[i].decl_filename = 0;
+
+ }
+
+ if (local_symbols[i].decl_start) {
+
+ free (local_symbols[i].decl_start);
+ local_symbols[i].decl_start = 0;
+
+ }
+
if (local_symbols[i].pointed_tag_name) {
free (local_symbols[i].pointed_tag_name);
}
+ if (local_symbols[i].decl_filename) {
+
+ free (local_symbols[i].decl_filename);
+ local_symbols[i].decl_filename = 0;
+
+ }
+
+ if (local_symbols[i].decl_start) {
+
+ free (local_symbols[i].decl_start);
+ local_symbols[i].decl_start = 0;
+
+ }
+
if (local_symbols[i].pointed_tag_name) {
free (local_symbols[i].pointed_tag_name);
local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = line;
+ local_symbols[local_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ local_symbols[local_symbol_count].decl_start = start ? xstrdup (start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = (start && caret && caret >= start) ? (long) (caret - start) : 0;
local_symbol_count++;
current_local_stack_size = new_size;
local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = line;
+ local_symbols[local_symbol_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ local_symbols[local_symbol_count].decl_start = start ? xstrdup (start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = (start && caret && caret >= start) ? (long) (caret - start) : 0;
local_symbol_count++;
static void set_local_symbol_array (const char *name, int is_array) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->is_array = is_array ? 1 : 0;
static void set_local_symbol_array_element_size (const char *name, int elem_size) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->array_element_size = elem_size > 0 ? elem_size : 0;
static void set_local_symbol_array_dimensions (const char *name, int dims) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (sym) {
sym->array_dimensions = dims > 0 ? dims : 0;
static void set_local_symbol_pointer_info (const char *name, int pointer_depth, int pointed_size) {
- struct local_symbol *sym = find_local_symbol (name);
+ struct local_symbol *sym = peek_local_symbol (name);
if (pointer_depth > 0 && parsed_type_is_aggregate && parsed_type_size > (DATA_PTR & 0x1f) && pointed_size <= (DATA_PTR & 0x1f)) {
pointed_size = parsed_type_size;
local_symbols[local_symbol_count].pointed_size = pending_params[i].pointed_size;
local_symbols[local_symbol_count].pointed_tag_name = pending_params[i].pointed_tag_name ? xstrdup (pending_params[i].pointed_tag_name) : 0;
local_symbols[local_symbol_count].tag_name = 0;
+ local_symbols[local_symbol_count].used = 0;
+ local_symbols[local_symbol_count].decl_line = pending_params[i].decl_line;
+ local_symbols[local_symbol_count].decl_filename = pending_params[i].decl_filename ? xstrdup (pending_params[i].decl_filename) : 0;
+ local_symbols[local_symbol_count].decl_start = pending_params[i].decl_start ? xstrdup (pending_params[i].decl_start) : 0;
+ local_symbols[local_symbol_count].decl_caret_offset = pending_params[i].decl_caret_offset;
local_symbol_count++;
slot_size = pending_params[i].size;
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
statement_ends_control_flow = block_ends_control_flow;
current_parse_block_depth--;
+ warn_unused_local_symbols (block_local_start, get_filename ());
truncate_local_symbols (block_local_start, block_stack_start);
}
*/
if (tok.kind != TOK_LPAREN && (name_is_function_designator || (find_global_symbol (name) >= 0 && get_global_symbol_kind (name) == GLOBAL_SYMBOL_FUNCTION))) {
+ {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0 && global_symbols[function_symbol_index].kind == GLOBAL_SYMBOL_FUNCTION) {
+ global_symbols[function_symbol_index].used = 1;
+ }
+
+ }
+
emit_load_address_to_reg_now (reg, name);
set_rhs_last_pointer_info (1, DATA_NONE);
return;
}
+ {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0 && global_symbols[function_symbol_index].kind == GLOBAL_SYMBOL_FUNCTION) {
+ global_symbols[function_symbol_index].used = 1;
+ }
+
+ }
+
inline_index = find_inline_function (name);
if (inline_index >= 0 &&
if (!declarator_is_pointer && parsed_type_tag_name[0]) {
- struct local_symbol *lsym = find_local_symbol (name);
+ struct local_symbol *lsym = peek_local_symbol (name);
if (lsym) {
lsym->tag_name = xstrdup (parsed_type_tag_name);
}
+ warn_unused_local_symbols (for_scope_start, get_filename ());
+
truncate_local_symbols (for_scope_start, for_stack_start);
statement_ends_control_flow = condition_is_infinite && !loop_escape_seen;
should_emit = add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 0, last_declarator_name_start, last_declarator_name_caret, last_declarator_name_line);
+ if (should_emit) {
+
+ int function_symbol_index = find_global_symbol (name);
+
+ if (function_symbol_index >= 0) {
+ global_symbols[function_symbol_index].is_static = (storage_class == STORAGE_STATIC);
+ }
+
+ }
+
set_global_symbol_size (name, return_is_void ? DATA_VOID : return_size);
set_global_symbol_unsigned (name, 0);
set_global_symbol_floating (name, return_is_floating);
}
+ warn_unused_local_symbols (0, function_filename_copy ? function_filename_copy : get_filename ());
+
reset_local_symbols ();
reset_goto_labels ();
masm_flush_data_line ();
}
+ warn_unused_static_functions (get_filename ());
emit_pending_extern_symbols ();
if (vec_dllexports.length || vec_dllaliases.length) {
return 0;
}
- if (find_local_symbol (tok.ident)) {
+ if (peek_local_symbol (tok.ident)) {
return 0;
}
pending_params[i].pointed_is_floating = 0;
pending_params[i].pointed_is_unsigned = 0;
pending_params[i].knr_declared = 0;
+ pending_params[i].decl_line = 0;
+ pending_params[i].decl_caret_offset = 0;
+
+ if (pending_params[i].decl_filename) {
+
+ free (pending_params[i].decl_filename);
+ pending_params[i].decl_filename = 0;
+
+ }
+
+ if (pending_params[i].decl_start) {
+
+ free (pending_params[i].decl_start);
+ pending_params[i].decl_start = 0;
+
+ }
if (pending_params[i].pointed_tag_name) {
struct local_symbol local_symbols[MAX_LOCAL_SYMBOLS];
int local_symbol_count = 0;
-struct local_symbol *find_local_symbol (const char *name) {
+struct local_symbol *peek_local_symbol (const char *name) {
int i;
}
+struct local_symbol *find_local_symbol (const char *name) {
+
+ struct local_symbol *sym = peek_local_symbol (name);
+
+ if (sym) {
+ sym->used = 1;
+ }
+
+ return sym;
+
+}
+
+void warn_unused_local_symbols (int start, const char *filename) {
+
+ int i;
+
+ if (!state || !(state->warn & WARN_UNUSED)) {
+ return;
+ }
+
+ if (start < 0) {
+ start = 0;
+ }
+
+ for (i = start; i < local_symbol_count; i++) {
+
+ struct local_symbol *sym = &local_symbols[i];
+
+ if (!sym->name || sym->used) {
+ continue;
+ }
+
+ if (sym->decl_start && sym->decl_line) {
+
+ report_line_at (sym->decl_filename ? sym->decl_filename : (filename ? filename : get_filename ()), sym->decl_line, REPORT_WARNING,
+ sym->decl_start, sym->decl_start + sym->decl_caret_offset,
+ "unused %s '%s'", sym->offset > 0 ? "parameter" : "variable", sym->name);
+
+ } else {
+
+ report_at (filename ? filename : get_filename (), get_line_number (), REPORT_WARNING,
+ "unused %s '%s'", sym->offset > 0 ? "parameter" : "variable", sym->name);
+
+ }
+
+ }
+
+}
+
+void warn_unused_static_functions (const char *filename) {
+
+ int i;
+
+ if (!state || !(state->warn & WARN_UNUSED)) {
+ return;
+ }
+
+ for (i = 0; i < global_symbol_count; i++) {
+
+ struct global_symbol_entry *sym = &global_symbols[i];
+
+ if (sym->kind != GLOBAL_SYMBOL_FUNCTION || !sym->is_static || sym->used || sym->is_extern) {
+ continue;
+ }
+
+ if (sym->decl_start && sym->decl_line) {
+
+ report_line_at (sym->decl_filename ? sym->decl_filename : (filename ? filename : get_filename ()), sym->decl_line, REPORT_WARNING,
+ sym->decl_start, sym->decl_start + sym->decl_caret_offset, "unused function '%s'", sym->name);
+
+ } else {
+ report_at (filename ? filename : get_filename (), get_line_number (), REPORT_WARNING, "unused function '%s'", sym->name);
+ }
+
+ }
+
+}
+
struct global_symbol_entry global_symbols[MAX_GLOBAL_SYMBOLS];
int global_symbol_count = 0;
pending_params[pending_param_count].pointed_is_floating = pointer_depth > 0 ? (parsed_type_is_floating ? 1 : 0) : 0;
pending_params[pending_param_count].pointed_is_unsigned = pointer_depth > 0 ? (pointed_is_unsigned ? 1 : 0) : 0;
pending_params[pending_param_count].pointed_tag_name = (pointer_depth > 0 && parsed_type_tag_name[0]) ? xstrdup (parsed_type_tag_name) : 0;
+ pending_params[pending_param_count].decl_line = last_declarator_name_line;
+ pending_params[pending_param_count].decl_filename = get_filename () ? xstrdup (get_filename ()) : 0;
+ pending_params[pending_param_count].decl_start = last_declarator_name_start ? xstrdup (last_declarator_name_start) : 0;
+ pending_params[pending_param_count].decl_caret_offset = (last_declarator_name_start && last_declarator_name_caret && last_declarator_name_caret >= last_declarator_name_start) ? (long) (last_declarator_name_caret - last_declarator_name_start) : 0;
pending_param_count++;
int pointed_is_unsigned;
char *pointed_tag_name;
+
char *tag_name;
+ int used;
+
+ unsigned long decl_line;
+
+ char *decl_filename;
+ char *decl_start;
+
+ long decl_caret_offset;
};
extern int local_symbol_count;
struct local_symbol *find_local_symbol (const char *name);
+struct local_symbol *peek_local_symbol (const char *name);
+
+void warn_unused_local_symbols (int start, const char *filename);
+void warn_unused_static_functions (const char *filename);
#define MAX_GLOBAL_SYMBOLS 4096
int find_global_symbol (const char *name);
int is_implicit;
int extern_emitted;
+ int is_static;
+ int used;
+
+ unsigned long decl_line;
+
+ char *decl_filename;
+ char *decl_start;
+
+ long decl_caret_offset;
+
enum token_kind calling_convention;
char *tag_name;
char *pointed_tag_name;
int knr_declared;
+
+ unsigned long decl_line;
+
+ char *decl_filename;
+ char *decl_start;
+
+ long decl_caret_offset;
};