Merge branch 'SiB64-strict-parameter-declaration'

Pulled from https://codeberg.org/SiB64/iverilog strict-parameter-declaration
with further enhancements.
This commit is contained in:
Martin Whitaker 2026-03-21 20:53:12 +00:00
commit 6767a07956
33 changed files with 237 additions and 16 deletions

View File

@ -131,6 +131,18 @@ These flags affect the general behavior of the compiler.
containing an unsized constant number, and unsized constant numbers are containing an unsized constant number, and unsized constant numbers are
not truncated to integer width. not truncated to integer width.
* strict-declaration/no-strict-declaration
* strict-net-var-declaration/no-strict-net-var-declaration
* strict-parameter-declaration/no-strict-parameter-declaration
The standards require that nets, variables, and parameters must be
declared lexically before they are used. Using -gno-strict-declaration
will allow using a data object before declaration, with a warning. The
warning can be suppressed with -Wno-declaration-after-use. The option
can be applied for nets and variables and for parameters separately.
* shared-loop-index/no-shared-loop-index * shared-loop-index/no-shared-loop-index
Enable or disable the exclusion of for-loop control variables from Enable or disable the exclusion of for-loop control variables from
@ -260,6 +272,7 @@ These flags affect the general behavior of the compiler.
-Wanachronisms -Wanachronisms
-Wimplicit -Wimplicit
-Wimplicit-dimensions -Wimplicit-dimensions
-Wdeclaration-after-use
-Wmacro-replacement -Wmacro-replacement
-Wportbind -Wportbind
-Wselect-range -Wselect-range
@ -288,6 +301,15 @@ These flags affect the general behavior of the compiler.
This flag is supported in release 10.1 or master branch snapshots after This flag is supported in release 10.1 or master branch snapshots after
2016-02-06. 2016-02-06.
* declaration-after-use
This enables warnings for declarations after use, when those are not
flagged as errors (enabled by default). Use no-declaration-after-use
to disable this.
This flag was added in version 14.0 or later (and is in the master branch
as of 2026-03-21).
* macro-redefinition * macro-redefinition
This enables warnings when a macro is redefined, even if the macro text This enables warnings when a macro is redefined, even if the macro text

View File

@ -1,7 +1,7 @@
#ifndef IVL_compiler_H #ifndef IVL_compiler_H
#define IVL_compiler_H #define IVL_compiler_H
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -104,6 +104,9 @@ extern bool warn_sens_entire_arr;
/* Warn about level-appropriate anachronisms. */ /* Warn about level-appropriate anachronisms. */
extern bool warn_anachronisms; extern bool warn_anachronisms;
/* Warn about declaration after use (unless flaged as errors). */
extern bool warn_decl_after_use;
/* Warn about nets that are references but not driven. */ /* Warn about nets that are references but not driven. */
extern bool warn_floating_nets; extern bool warn_floating_nets;
@ -210,6 +213,20 @@ extern bool gn_strict_expr_width_flag;
loop. */ loop. */
extern bool gn_shared_loop_index_flag; extern bool gn_shared_loop_index_flag;
/* If this flag is true (default), then parameters must be declared before
use. `-gno-strict[-parameter]-declaration` allows to use parameters before
declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_parameter_declaration;
/* If this flag is true (default), then nets and variablesmust be declared
before use. `-gno-strict[-net-var]-declaration` allows to use nets and
variables before declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_net_var_declaration;
static inline bool gn_system_verilog(void) static inline bool gn_system_verilog(void)
{ {
if (generation_flag >= GN_VER2005_SV) if (generation_flag >= GN_VER2005_SV)

View File

@ -124,7 +124,7 @@ to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system. new keywords used to implement the type system.
.TP 8 .TP 8
.B -gio-range-error\fI|\fP-gno-io-range-error .B -gio-range-error\fI|\fP-gno-io-range-error
The standards requires that a vectored port have matching ranges for its The standards require that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is declaration and some tools still allow this. By default any mismatch is
@ -150,6 +150,17 @@ parameter assignment is evaluated as a lossless expression, as is any
expression containing an unsized constant number, and unsized constant expression containing an unsized constant number, and unsized constant
numbers are not truncated to integer width. numbers are not truncated to integer width.
.TP 8 .TP 8
.B -gstrict-declaration\fI|\fP-gno-strict-declaration
.TP 8
.B -gstrict-net-var-declaration\fI|\fP-gno-strict-net-var-declaration
.TP 8
.B -gstrict-parameter-declaration\fI|\fP-gno-strict-parameter-declaration
The standards require that nets, variables, and parameters are declared
lexically before they are used. Using \fB\-gno\-strict\-declaration\fP
will allow using a data object before declaration, with a warning. The
warning can be suppressed with -Wno-declaration-after-use. The option
can be applied for nets and variables and for parameters separately.
.TP 8
.B -gshared-loop-index\fI|\fP-gno-shared-loop-index .B -gshared-loop-index\fI|\fP-gno-shared-loop-index
Enable (default) or disable the exclusion of for-loop control variables Enable (default) or disable the exclusion of for-loop control variables
from implicit event_expression lists. When enabled, if a for-loop control from implicit event_expression lists. When enabled, if a for-loop control
@ -367,6 +378,11 @@ This enables warnings for creation of implicit declarations. For
example, if a scalar wire X is used but not declared in the Verilog example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use. source, this will print a warning at its first use.
.TP 8
.B declaration-after-use
This enables warnings for declarations after use, when
those are not flagged as errors (default).
.TP 8 .TP 8
.B macro-redefinition\fI | \fPmacro-replacement .B macro-redefinition\fI | \fPmacro-replacement
This enables preprocessor warnings when a macro is being redefined. This enables preprocessor warnings when a macro is being redefined.

View File

@ -134,6 +134,8 @@ const char*gen_strict_ca_eval = "no-strict-ca-eval";
const char*gen_strict_expr_width = "no-strict-expr-width"; const char*gen_strict_expr_width = "no-strict-expr-width";
const char*gen_shared_loop_index = "shared-loop-index"; const char*gen_shared_loop_index = "shared-loop-index";
const char*gen_verilog_ams = "no-verilog-ams"; const char*gen_verilog_ams = "no-verilog-ams";
const char*gen_strict_net_var_declaration = "strict-net-var-declaration";
const char*gen_strict_parameter_declaration = "strict-parameter-declaration";
/* Boolean: true means use a default include dir, false means don't */ /* Boolean: true means use a default include dir, false means don't */
int gen_std_include = 1; int gen_std_include = 1;
@ -142,7 +144,7 @@ int gen_std_include = 1;
of the include list. */ of the include list. */
int gen_relative_include = 0; int gen_relative_include = 0;
char warning_flags[17] = "n"; char warning_flags[18] = "nu";
int separate_compilation_flag = 0; int separate_compilation_flag = 0;
@ -527,6 +529,7 @@ static void process_warning_switch(const char*name)
{ {
if (strcmp(name,"all") == 0) { if (strcmp(name,"all") == 0) {
process_warning_switch("anachronisms"); process_warning_switch("anachronisms");
process_warning_switch("declaration-after-use");
process_warning_switch("implicit"); process_warning_switch("implicit");
process_warning_switch("implicit-dimensions"); process_warning_switch("implicit-dimensions");
process_warning_switch("macro-replacement"); process_warning_switch("macro-replacement");
@ -537,6 +540,9 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"anachronisms") == 0) { } else if (strcmp(name,"anachronisms") == 0) {
if (! strchr(warning_flags, 'n')) if (! strchr(warning_flags, 'n'))
strcat(warning_flags, "n"); strcat(warning_flags, "n");
} else if (strcmp(name,"declaration-after-use") == 0) {
if (! strchr(warning_flags, 'u'))
strcat(warning_flags, "u");
} else if (strcmp(name,"floating-nets") == 0) { } else if (strcmp(name,"floating-nets") == 0) {
if (! strchr(warning_flags, 'f')) if (! strchr(warning_flags, 'f'))
strcat(warning_flags, "f"); strcat(warning_flags, "f");
@ -578,6 +584,12 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1]; cp[0] = cp[1];
cp += 1; cp += 1;
} }
} else if (strcmp(name,"no-declaration-after-use") == 0) {
char*cp = strchr(warning_flags, 'u');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-floating-nets") == 0) { } else if (strcmp(name,"no-floating-nets") == 0) {
char*cp = strchr(warning_flags, 'f'); char*cp = strchr(warning_flags, 'f');
if (cp) while (*cp) { if (cp) while (*cp) {
@ -815,6 +827,26 @@ static int process_generation(const char*name)
else if (strcmp(name,"no-verilog-ams") == 0) else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams"; gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"strict-declaration") == 0) {
gen_strict_net_var_declaration = "strict-net-var-declaration";
gen_strict_parameter_declaration = "strict-parameter-declaration";
}
else if (strcmp(name,"no-strict-declaration") == 0) {
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
}
else if (strcmp(name,"strict-net-var-declaration") == 0)
gen_strict_net_var_declaration = "strict-net-var-declaration";
else if (strcmp(name,"no-strict-net-var-declaration") == 0)
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
else if (strcmp(name,"strict-parameter-declaration") == 0)
gen_strict_parameter_declaration = "strict-parameter-declaration";
else if (strcmp(name,"no-strict-parameter-declaration") == 0)
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
else { else {
fprintf(stderr, "Unknown/Unsupported Language generation " fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name); "%s\n\n", name);
@ -837,7 +869,9 @@ static int process_generation(const char*name)
" io-range-error | no-io-range-error\n" " io-range-error | no-io-range-error\n"
" strict-ca-eval | no-strict-ca-eval\n" " strict-ca-eval | no-strict-ca-eval\n"
" strict-expr-width | no-strict-expr-width\n" " strict-expr-width | no-strict-expr-width\n"
" shared-loop-index | no-shared-loop-index\n"); " shared-loop-index | no-shared-loop-index\n"
" strict-declaration | no-strict-declaration\n"
" [no-]strict-[net-var|parameter]-declaration\n");
return 1; return 1;
} }
@ -1385,6 +1419,8 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width); fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index); fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams); fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_strict_net_var_declaration);
fprintf(iconfig_file, "generation:%s\n", gen_strict_parameter_declaration);
fprintf(iconfig_file, "generation:%s\n", gen_icarus); fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "warnings:%s\n", warning_flags); fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false"); fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false");

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use1.v:4: warning: net/variable `v` used before declaration.
ivltests/decl_before_use1.v:9: : the net/variable is declared here.

View File

@ -0,0 +1,2 @@
1
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use2.v:3: warning: net/variable `w` used before declaration.
ivltests/decl_before_use2.v:10: : the net/variable is declared here.

View File

@ -0,0 +1,2 @@
00000001
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use3.v:4: warning: event `e` used before declaration.
ivltests/decl_before_use3.v:8: : the event is declared here.

View File

@ -0,0 +1 @@
used before declaration

View File

@ -0,0 +1 @@
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use5.v:4: warning: parameter `w` used before declaration.
ivltests/decl_before_use5.v:8: : the parameter is declared here.

View File

@ -0,0 +1,2 @@
10101010
used before declaration

View File

@ -0,0 +1,2 @@
10
FAILED

View File

@ -0,0 +1,3 @@
./ivltests/pr1909940.v:4: warning: net/variable `in` used before declaration.
./ivltests/pr1909940.v:5: : the net/variable is declared here.
PASSED

View File

@ -0,0 +1,3 @@
./ivltests/pr1909940b.v:4: warning: net/variable `in` used before declaration.
./ivltests/pr1909940b.v:5: : the net/variable is declared here.
PASSED

View File

@ -3,7 +3,7 @@ module test();
initial begin initial begin
v = 1; v = 1;
$display("%b", v); $display("%b", v);
$display("FAILED"); $display("used before declaration");
end end
reg v; reg v;

View File

@ -4,7 +4,7 @@ assign w = 1;
initial begin initial begin
$display("%b", w); $display("%b", w);
$display("FAILED"); $display("used before declaration");
end end
wire [7:0] w; wire [7:0] w;

View File

@ -2,7 +2,7 @@ module test();
initial begin initial begin
->e; ->e;
$display("FAILED"); $display("used before declaration");
end end
event e; event e;

View File

@ -2,7 +2,7 @@ module test();
initial begin initial begin
@(e); @(e);
$display("FAILED"); $display("used before declaration");
end end
event e; event e;

View File

@ -2,7 +2,7 @@ module test();
initial begin initial begin
$display("%b", w); $display("%b", w);
$display("FAILED"); $display("used before declaration");
end end
localparam w = 8'hAA; localparam w = 8'hAA;

View File

@ -1126,8 +1126,8 @@ pr1903324 normal ivltests
pr1903343 normal ivltests gold=pr1903343.gold pr1903343 normal ivltests gold=pr1903343.gold
pr1903520 normal ivltests pr1903520 normal ivltests
pr1907192 normal ivltests pr1907192 normal ivltests
pr1909940 CE ivltests pr1909940 normal,-gno-strict-declaration ivltests gold=pr1909940.gold
pr1909940b CE ivltests pr1909940b normal,-gno-strict-declaration ivltests gold=pr1909940b.gold
pr1912843 normal ivltests pr1912843 normal ivltests
pr1913918a normal ivltests pr1913918a normal ivltests
pr1913918b normal ivltests pr1913918b normal ivltests

View File

@ -97,6 +97,12 @@ decl_before_use3 vvp_tests/decl_before_use3.json
decl_before_use4 vvp_tests/decl_before_use4.json decl_before_use4 vvp_tests/decl_before_use4.json
decl_before_use5 vvp_tests/decl_before_use5.json decl_before_use5 vvp_tests/decl_before_use5.json
decl_before_use6 vvp_tests/decl_before_use6.json decl_before_use6 vvp_tests/decl_before_use6.json
decl_before_use1_warn vvp_tests/decl_before_use1_warn.json
decl_before_use2_warn vvp_tests/decl_before_use2_warn.json
decl_before_use3_warn vvp_tests/decl_before_use3_warn.json
decl_before_use4_warn vvp_tests/decl_before_use4_warn.json
decl_before_use5_warn vvp_tests/decl_before_use5_warn.json
decl_before_use6_warn vvp_tests/decl_before_use6_warn.json
delayed_sfunc vvp_tests/delayed_sfunc.json delayed_sfunc vvp_tests/delayed_sfunc.json
dffsynth vvp_tests/dffsynth.json dffsynth vvp_tests/dffsynth.json
dffsynth-S vvp_tests/dffsynth-S.json dffsynth-S vvp_tests/dffsynth-S.json

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use1.v",
"iverilog-args" : [ "-gno-strict-net-var-declaration" ],
"gold" : "decl_before_use1_warn"
}

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use2.v",
"iverilog-args" : [ "-gno-strict-declaration" ],
"gold" : "decl_before_use2_warn"
}

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use3.v",
"iverilog-args" : [ "-gno-strict-net-var-declaration" ],
"gold" : "decl_before_use3_warn"
}

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use4.v",
"iverilog-args" : [ "-gno-strict-declaration", "-Wno-declaration-after-use" ],
"gold" : "decl_before_use4_warn"
}

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use5.v",
"iverilog-args" : [ "-gno-strict-parameter-declaration" ],
"gold" : "decl_before_use5_warn"
}

View File

@ -0,0 +1,7 @@
{
"type" : "normal",
"source" : "decl_before_use6.v",
"iverilog-args" : [ "-gno-strict-declaration", "-Wno-declaration-after-use" ],
"gold" : "decl_before_use6_warn"
}

18
main.cc
View File

@ -117,6 +117,8 @@ bool gn_strict_ca_eval_flag = false;
bool gn_strict_expr_width_flag = false; bool gn_strict_expr_width_flag = false;
bool gn_shared_loop_index_flag = true; bool gn_shared_loop_index_flag = true;
bool gn_verilog_ams_flag = false; bool gn_verilog_ams_flag = false;
bool gn_strict_parameter_declaration = true;
bool gn_strict_net_var_declaration = true;
/* /*
* For some generations we allow a system function to be called * For some generations we allow a system function to be called
@ -172,6 +174,7 @@ bool warn_ob_select = false;
bool warn_sens_entire_vec = false; bool warn_sens_entire_vec = false;
bool warn_sens_entire_arr = false; bool warn_sens_entire_arr = false;
bool warn_anachronisms = false; bool warn_anachronisms = false;
bool warn_decl_after_use = false;
bool warn_floating_nets = false; bool warn_floating_nets = false;
/* /*
@ -386,6 +389,18 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"no-shared-loop-index") == 0) { } else if (strcmp(gen,"no-shared-loop-index") == 0) {
gn_shared_loop_index_flag = false; gn_shared_loop_index_flag = false;
} else if (strcmp(gen,"strict-parameter-declaration") == 0) {
gn_strict_parameter_declaration = true;
} else if (strcmp(gen,"no-strict-parameter-declaration") == 0) {
gn_strict_parameter_declaration = false;
} else if (strcmp(gen,"strict-net-var-declaration") == 0) {
gn_strict_net_var_declaration = true;
} else if (strcmp(gen,"no-strict-net-var-declaration") == 0) {
gn_strict_net_var_declaration = false;
} else { } else {
} }
} }
@ -760,6 +775,9 @@ static void read_iconfig_file(const char*ipath)
case 'n': case 'n':
warn_anachronisms = true; warn_anachronisms = true;
break; break;
case 'u':
warn_decl_after_use = true;
break;
default: default:
break; break;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2026 Stephen Williams (steve@icarus.com)
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch) * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -462,6 +462,14 @@ unsigned NetScope::get_parameter_lexical_pos(perm_string key) const
return 0; return 0;
} }
void NetScope::set_parameter_lexical_pos(perm_string key, unsigned lexical_pos)
{
map<perm_string,param_expr_t>::iterator idx;
idx = parameters.find(key);
if (idx != parameters.end()) idx->second.lexical_pos = lexical_pos;
}
void NetScope::print_type(ostream&stream) const void NetScope::print_type(ostream&stream) const
{ {
switch (type_) { switch (type_) {

View File

@ -1274,6 +1274,7 @@ class NetScope : public Definitions, public Attrib {
LineInfo get_parameter_line_info(perm_string name) const; LineInfo get_parameter_line_info(perm_string name) const;
unsigned get_parameter_lexical_pos(perm_string name) const; unsigned get_parameter_lexical_pos(perm_string name) const;
void set_parameter_lexical_pos(perm_string name, unsigned lexical_pos);
/* Module instance arrays are collected here for access during /* Module instance arrays are collected here for access during
the multiple elaboration passes. */ the multiple elaboration passes. */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-2024 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2026 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -164,12 +164,22 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
} }
if (NetNet*net = scope->find_signal(path_tail.name)) { if (NetNet*net = scope->find_signal(path_tail.name)) {
if (prefix_scope || (net->lexical_pos() <= lexical_pos)) { bool decl_after_use = !prefix_scope && !(net->lexical_pos() <= lexical_pos);
if (!gn_strict_net_var_declaration || !decl_after_use) {
path.push_back(path_tail); path.push_back(path_tail);
res->scope = scope; res->scope = scope;
res->net = net; res->net = net;
res->type = net->net_type(); res->type = net->net_type();
res->path_head = path; res->path_head = path;
if (warn_decl_after_use && decl_after_use) {
cerr << li->get_fileline()
<< ": warning: net/variable `" << path_tail.name
<< "` used before declaration." << endl;
cerr << net->get_fileline()
<< ": : the net/variable is declared here." << endl;
// suppress further warnings for this net
net->lexical_pos(lexical_pos);
}
return true; return true;
} else if (!res->decl_after_use) { } else if (!res->decl_after_use) {
res->decl_after_use = net; res->decl_after_use = net;
@ -177,11 +187,21 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
} }
if (NetEvent*eve = scope->find_event(path_tail.name)) { if (NetEvent*eve = scope->find_event(path_tail.name)) {
if (prefix_scope || (eve->lexical_pos() <= lexical_pos)) { bool decl_after_use = !prefix_scope && !(eve->lexical_pos() <= lexical_pos);
if (!gn_strict_net_var_declaration || !decl_after_use) {
path.push_back(path_tail); path.push_back(path_tail);
res->scope = scope; res->scope = scope;
res->eve = eve; res->eve = eve;
res->path_head = path; res->path_head = path;
if (warn_decl_after_use && decl_after_use) {
cerr << li->get_fileline()
<< ": warning: event `" << path_tail.name
<< "` used before declaration." << endl;
cerr << eve->get_fileline()
<< ": : the event is declared here." << endl;
// suppress further warnings for this event
eve->lexical_pos(lexical_pos);
}
return true; return true;
} else if (!res->decl_after_use) { } else if (!res->decl_after_use) {
res->decl_after_use = eve; res->decl_after_use = eve;
@ -189,11 +209,22 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
} }
if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->type)) { if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->type)) {
if (prefix_scope || (scope->get_parameter_lexical_pos(path_tail.name) <= lexical_pos)) { bool decl_after_use = !prefix_scope
&& !(scope->get_parameter_lexical_pos(path_tail.name) <= lexical_pos);
if (!gn_strict_parameter_declaration || !decl_after_use) {
path.push_back(path_tail); path.push_back(path_tail);
res->scope = scope; res->scope = scope;
res->par_val = par; res->par_val = par;
res->path_head = path; res->path_head = path;
if (warn_decl_after_use && decl_after_use) {
cerr << li->get_fileline()
<< ": warning: parameter `" << path_tail.name
<< "` used before declaration." << endl;
cerr << par->get_fileline()
<< ": : the parameter is declared here." << endl;
// suppress further warnings for this parameter
scope->set_parameter_lexical_pos(path_tail.name, lexical_pos);
}
return true; return true;
} else if (!res->decl_after_use) { } else if (!res->decl_after_use) {
res->decl_after_use = par; res->decl_after_use = par;