diff options
| author | Zachary Snow <zach@zachjs.com> | 2021-07-15 10:36:50 -0400 | 
|---|---|---|
| committer | Zachary Snow <zachary.j.snow@gmail.com> | 2021-07-28 21:52:16 -0400 | 
| commit | 3156226233133f5da9dba15c63ca560b4794b831 (patch) | |
| tree | 9d45120e6b8554df2c1b1f71cf90ea0fc124f270 /frontends/verilog | |
| parent | a055145b95b08bc97f3e3ee27842576d8ea09a94 (diff) | |
| download | yosys-3156226233133f5da9dba15c63ca560b4794b831.tar.gz yosys-3156226233133f5da9dba15c63ca560b4794b831.tar.bz2 yosys-3156226233133f5da9dba15c63ca560b4794b831.zip | |
verilog: save and restore overwritten macro arguments
Diffstat (limited to 'frontends/verilog')
| -rw-r--r-- | frontends/verilog/preproc.cc | 34 | ||||
| -rw-r--r-- | frontends/verilog/preproc.h | 1 | 
2 files changed, 31 insertions, 4 deletions
| diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 4b9ebe0aa..17f567587 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -36,6 +36,7 @@  #include "verilog_frontend.h"  #include "kernel/log.h"  #include <assert.h> +#include <stack>  #include <stdarg.h>  #include <stdio.h>  #include <string.h> @@ -334,6 +335,11 @@ define_map_t::add(const std::string &name, const std::string &txt, const arg_map  	defines[name] = std::unique_ptr<define_body_t>(new define_body_t(txt, args));  } +void define_map_t::add(const std::string &name, const define_body_t &body) +{ +	defines[name] = std::unique_ptr<define_body_t>(new define_body_t(body)); +} +  void define_map_t::merge(const define_map_t &map)  {  	for (const auto &pr : map.defines) { @@ -440,7 +446,17 @@ static bool read_argument(std::string &dest)  	}  } -static bool try_expand_macro(define_map_t &defines, std::string &tok) +using macro_arg_stack_t = std::stack<std::pair<std::string, define_body_t>>; + +static void restore_macro_arg(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack) +{ +	log_assert(!macro_arg_stack.empty()); +	auto &overwritten_arg = macro_arg_stack.top(); +	defines.add(overwritten_arg.first, overwritten_arg.second); +	macro_arg_stack.pop(); +} + +static bool try_expand_macro(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack, std::string &tok)  {  	if (tok == "`\"") {  		std::string literal("\""); @@ -450,7 +466,7 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok)  			if (ntok == "`\"") {  				insert_input(literal+"\"");  				return true; -			} else if (!try_expand_macro(defines, ntok)) { +			} else if (!try_expand_macro(defines, macro_arg_stack, ntok)) {  					literal += ntok;  			}  		} @@ -495,6 +511,10 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok)  			args.push_back(arg);  		}  		for (const auto &pr : body->args.get_vals(name, args)) { +			if (const define_body_t *existing = defines.find(pr.first)) { +				macro_arg_stack.push({pr.first, *existing}); +				insert_input("`__restore_macro_arg "); +			}  			defines.add(pr.first, pr.second);  		}  	} else { @@ -725,6 +745,7 @@ frontend_verilog_preproc(std::istream                 &f,  	defines.merge(pre_defines);  	defines.merge(global_defines_cache); +	macro_arg_stack_t macro_arg_stack;  	std::vector<std::string> filename_stack;  	// We are inside pass_level levels of satisfied ifdefs, and then within  	// fail_level levels of unsatisfied ifdefs.  The unsatisfied ones are @@ -828,7 +849,7 @@ frontend_verilog_preproc(std::istream                 &f,  		if (tok == "`include") {  			skip_spaces();  			std::string fn = next_token(true); -			while (try_expand_macro(defines, fn)) { +			while (try_expand_macro(defines, macro_arg_stack, fn)) {  				fn = next_token();  			}  			while (1) { @@ -935,7 +956,12 @@ frontend_verilog_preproc(std::istream                 &f,  			continue;  		} -		if (try_expand_macro(defines, tok)) +		if (tok == "`__restore_macro_arg") { +			restore_macro_arg(defines, macro_arg_stack); +			continue; +		} + +		if (try_expand_macro(defines, macro_arg_stack, tok))  			continue;  		output_code.push_back(tok); diff --git a/frontends/verilog/preproc.h b/frontends/verilog/preproc.h index e1048156c..330855a92 100644 --- a/frontends/verilog/preproc.h +++ b/frontends/verilog/preproc.h @@ -42,6 +42,7 @@ struct define_map_t  	// Add a definition, overwriting any existing definition for name.  	void add(const std::string &name, const std::string &txt, const arg_map_t *args = nullptr); +	void add(const std::string &name, const define_body_t &body);  	// Merge in another map of definitions (which take precedence  	// over anything currently defined). | 
