Added unused warnings
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 11:07:02 +0000 (12:07 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 11:07:02 +0000 (12:07 +0100)
amd64.c
i386.c
parse.c
parse.h

diff --git a/amd64.c b/amd64.c
index be75f5d7cc08f0c94641b8435d305f79fa1d7415..26b4360d0c6b51e4ee791bcfc0d02502c9764544 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -484,6 +484,25 @@ static void clear_global_symbols (void) {
         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) {
         
@@ -1167,6 +1186,12 @@ static int add_global_symbol (const char *name, int kind, int is_extern, const c
     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++;
@@ -5660,6 +5685,20 @@ static void reset_local_symbols (void) {
         
         }
         
+        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);
@@ -5711,6 +5750,20 @@ static void truncate_local_symbols (int count, long stack_size) {
         
         }
         
+        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);
@@ -5817,6 +5870,11 @@ static long add_local_symbol (const char *name, int size, int align, int is_unsi
     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;
@@ -5874,6 +5932,11 @@ static void add_static_local_symbol (const char *name, const char *label, int si
     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++;
 
@@ -5881,7 +5944,7 @@ static void add_static_local_symbol (const char *name, const char *label, int si
 
 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;
@@ -5891,7 +5954,7 @@ static void set_local_symbol_array (const char *name, int is_array) {
 
 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;
@@ -5901,7 +5964,7 @@ static void set_local_symbol_array_element_size (const char *name, int elem_size
 
 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;
@@ -6087,7 +6150,7 @@ static void copy_pending_params_to_global_symbol (const char *name) {
 
 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;
@@ -6157,6 +6220,11 @@ static void install_pending_params_as_locals (void) {
         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;
@@ -8798,7 +8866,7 @@ static void parse_block (void) {
                     
                     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);
@@ -9193,7 +9261,7 @@ static void parse_block (void) {
                     
                     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);
@@ -9364,6 +9432,7 @@ static void parse_block (void) {
     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);
 
 }
@@ -20837,6 +20906,16 @@ static void emit_load_assignment_rhs_to_reg (const char *reg) {
          */
         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);
             
@@ -25982,6 +26061,16 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
         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 &&
@@ -34783,7 +34872,7 @@ static void parse_for_init_declaration (int scope_start, long stack_start, long
         
         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);
@@ -35006,6 +35095,8 @@ static void parse_for_statement (void) {
     
     }
     
+    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;
 
@@ -38061,6 +38152,16 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
         
         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);
@@ -38219,6 +38320,8 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     
     }
     
+    warn_unused_local_symbols (0, function_filename_copy ? function_filename_copy : get_filename ());
+    
     reset_local_symbols ();
     reset_goto_labels ();
     
@@ -40118,6 +40221,7 @@ void compile_translation_unit64 (void) {
         masm_flush_data_line ();
     }
     
+    warn_unused_static_functions (get_filename ());
     emit_pending_extern_symbols ();
     
     if (vec_dllexports.length || vec_dllaliases.length) {
diff --git a/i386.c b/i386.c
index 99a3acd8fec644b49b5209cf423dc589610412ce..ad89ec59fb5e33a099ff4b64fea608ba33f0c509 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -284,6 +284,25 @@ static void clear_global_symbols (void) {
         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) {
         
@@ -981,6 +1000,12 @@ static int add_global_symbol (const char *name, int kind, int is_extern, const c
     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++;
@@ -5341,6 +5366,20 @@ static void reset_local_symbols (void) {
         
         }
         
+        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);
@@ -5391,6 +5430,20 @@ static void truncate_local_symbols (int count, long stack_size) {
         
         }
         
+        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);
@@ -5497,6 +5550,11 @@ static long add_local_symbol (const char *name, int size, int align, int is_unsi
     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;
@@ -5554,6 +5612,11 @@ static void add_static_local_symbol (const char *name, const char *label, int si
     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++;
 
@@ -5561,7 +5624,7 @@ static void add_static_local_symbol (const char *name, const char *label, int si
 
 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;
@@ -5571,7 +5634,7 @@ static void set_local_symbol_array (const char *name, int is_array) {
 
 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;
@@ -5581,7 +5644,7 @@ static void set_local_symbol_array_element_size (const char *name, int elem_size
 
 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;
@@ -5767,7 +5830,7 @@ static void copy_pending_params_to_global_symbol (const char *name) {
 
 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;
@@ -5837,6 +5900,11 @@ static void install_pending_params_as_locals (void) {
         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;
@@ -8036,7 +8104,7 @@ static void parse_block (void) {
                     
                     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);
@@ -8434,7 +8502,7 @@ static void parse_block (void) {
                     
                     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);
@@ -8605,6 +8673,7 @@ static void parse_block (void) {
     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);
 
 }
@@ -19598,6 +19667,16 @@ static void emit_load_assignment_rhs_to_reg (const char *reg) {
          */
         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);
             
@@ -23220,6 +23299,16 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
         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 &&
@@ -32262,7 +32351,7 @@ static void parse_for_init_declaration (int scope_start, long stack_start, long
         
         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);
@@ -32485,6 +32574,8 @@ static void parse_for_statement (void) {
     
     }
     
+    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;
 
@@ -35508,6 +35599,16 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
         
         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);
@@ -35661,6 +35762,8 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     
     }
     
+    warn_unused_local_symbols (0, function_filename_copy ? function_filename_copy : get_filename ());
+    
     reset_local_symbols ();
     reset_goto_labels ();
     
@@ -37455,6 +37558,7 @@ void compile_translation_unit32 (void) {
         masm_flush_data_line ();
     }
     
+    warn_unused_static_functions (get_filename ());
     emit_pending_extern_symbols ();
     
     if (vec_dllexports.length || vec_dllaliases.length) {
diff --git a/parse.c b/parse.c
index 3f30111ff9e6b5681c7a0c139696db71948a6b7a..2ad1400ded4f115f4cce023fc54c053f5a1847b2 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -249,7 +249,7 @@ static int is_current_typedef_name (void) {
         return 0;
     }
     
-    if (find_local_symbol (tok.ident)) {
+    if (peek_local_symbol (tok.ident)) {
         return 0;
     }
     
@@ -799,6 +799,22 @@ void clear_pending_params (void) {
         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) {
         
@@ -2257,7 +2273,7 @@ int resolve_enum_constant (const char *name, int64_s *out) {
 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;
     
@@ -2277,6 +2293,84 @@ struct local_symbol *find_local_symbol (const char *name) {
 
 }
 
+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;
 
@@ -2601,6 +2695,10 @@ void add_pending_param (const char *name, int size, int align, int is_unsigned,
     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++;
 
diff --git a/parse.h b/parse.h
index 75de67d97918176053dd3aa64426ec1e9aa03f16..8b52fd891223c9410f750f87f91d0b4937af47f2 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -179,7 +179,16 @@ struct local_symbol {
     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;
 
 };
 
@@ -204,6 +213,10 @@ extern struct local_symbol local_symbols[MAX_LOCAL_SYMBOLS];
 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);
@@ -246,6 +259,16 @@ struct global_symbol_entry {
     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;
 
@@ -323,6 +346,13 @@ struct pending_param {
     
     char *pointed_tag_name;
     int knr_declared;
+    
+    unsigned long decl_line;
+    
+    char *decl_filename;
+    char *decl_start;
+    
+    long decl_caret_offset;
 
 };