aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog')
-rw-r--r--frontends/verilog/preproc.cc49
1 files changed, 38 insertions, 11 deletions
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index de707593f..84966e501 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -727,7 +727,8 @@ frontend_verilog_preproc(std::istream &f,
std::vector<std::string> filename_stack;
int ifdef_fail_level = 0;
- bool in_elseif = false;
+ int ifdef_pass_level = 0;
+ bool ifdef_already_satisfied = false;
output_code.clear();
input_buffer.clear();
@@ -743,42 +744,68 @@ frontend_verilog_preproc(std::istream &f,
if (tok == "`endif") {
if (ifdef_fail_level > 0)
ifdef_fail_level--;
- if (ifdef_fail_level == 0)
- in_elseif = false;
+ else if (ifdef_pass_level > 0)
+ ifdef_already_satisfied = --ifdef_pass_level;
+ else
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
continue;
}
if (tok == "`else") {
- if (ifdef_fail_level == 0)
+ if (ifdef_fail_level == 0) {
+ if (ifdef_pass_level == 0)
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
+ log_assert(ifdef_already_satisfied);
ifdef_fail_level = 1;
- else if (ifdef_fail_level == 1 && !in_elseif)
+ } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied) {
ifdef_fail_level = 0;
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
continue;
}
if (tok == "`elsif") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level == 0)
- ifdef_fail_level = 1, in_elseif = true;
- else if (ifdef_fail_level == 1 && defines.find(name))
- ifdef_fail_level = 0, in_elseif = true;
+ if (ifdef_fail_level == 0) {
+ if (ifdef_pass_level == 0)
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
+ log_assert(ifdef_already_satisfied);
+ ifdef_fail_level = 1;
+ } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied && defines.find(name)) {
+ ifdef_fail_level = 0;
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
continue;
}
if (tok == "`ifdef") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level > 0 || !defines.find(name))
+ if (ifdef_fail_level > 0 || !defines.find(name)) {
ifdef_fail_level++;
+ } else {
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
+ if (ifdef_fail_level == 1)
+ ifdef_already_satisfied = false;
continue;
}
if (tok == "`ifndef") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level > 0 || defines.find(name))
+ if (ifdef_fail_level > 0 || defines.find(name)) {
ifdef_fail_level++;
+ } else {
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
+ if (ifdef_fail_level == 1)
+ ifdef_already_satisfied = false;
continue;
}