mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	verilog: fix handling of nested ifdef directives
- track depth so we know whether to consider higher-level elsifs - error on unmatched endif/elsif/else
This commit is contained in:
		
							parent
							
								
									b6904a8e53
								
							
						
					
					
						commit
						1ec5994100
					
				
					 8 changed files with 197 additions and 11 deletions
				
			
		|  | @ -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; | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue