mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	verilog: save and restore overwritten macro arguments
This commit is contained in:
		
							parent
							
								
									a055145b95
								
							
						
					
					
						commit
						3156226233
					
				
					 4 changed files with 54 additions and 4 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -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).
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue