From 778dbc86b3c2d09fc6cc62908bba00770b3e98a2 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Mon, 25 Sep 2023 14:34:16 -0700 Subject: [PATCH] Verilog preprocessor: implement multi-line defines This implements multi-line macros in the Verilog preprocessor. --- .../verilog/preprocessor/multi-line-define1.desc | 14 ++++++++++++++ .../verilog/preprocessor/multi-line-define1.v | 4 ++++ src/verilog/verilog_preprocessor.cpp | 14 ++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 regression/verilog/preprocessor/multi-line-define1.desc create mode 100644 regression/verilog/preprocessor/multi-line-define1.v diff --git a/regression/verilog/preprocessor/multi-line-define1.desc b/regression/verilog/preprocessor/multi-line-define1.desc new file mode 100644 index 000000000..d442c329e --- /dev/null +++ b/regression/verilog/preprocessor/multi-line-define1.desc @@ -0,0 +1,14 @@ +CORE +multi-line-define1.v +--preprocess +// Enable multi-line checking +activate-multi-line-match +`line 1 "multi-line-define1.v" 0 + +A +B +C +^EXIT=0$ +^SIGNAL=0$ +-- +^PREPROCESSING FAILED$ diff --git a/regression/verilog/preprocessor/multi-line-define1.v b/regression/verilog/preprocessor/multi-line-define1.v new file mode 100644 index 000000000..d846998f9 --- /dev/null +++ b/regression/verilog/preprocessor/multi-line-define1.v @@ -0,0 +1,4 @@ +`define foo A \ +B \ +C +`foo diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 6bdc2681d..d9a398f35 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -362,13 +362,23 @@ void verilog_preprocessort::directive() // skip whitespace tokenizer().skip_ws(); - // Read any tokens until end of line. + // Read any tokens until end of line, + // but note that \n can be escaped with a backslash. // Note that any defines in this sequence // are not expanded at this point. while(!tokenizer().eof() && tokenizer().peek() != '\n') { auto token = tokenizer().next_token(); - define.tokens.push_back(std::move(token)); + if(token == '\\' && tokenizer().peek() == '\n') + { + // Eat the newline, which is escaped. + // Not clear whether the newline is meant to show + // in the expansion. + auto nl = tokenizer().next_token(); + define.tokens.push_back(std::move(nl)); + } + else + define.tokens.push_back(std::move(token)); } #ifdef DEBUG