mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge pull request #1718 from boqwxp/precise_locations
Closes #1717. Add more precise Verilog source location information to AST and RTLIL nodes.
This commit is contained in:
		
						commit
						b597f85b13
					
				
					 11 changed files with 388 additions and 305 deletions
				
			
		|  | @ -53,7 +53,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg | |||
| 		{ | ||||
| 			// If there's no next character, that's a problem
 | ||||
| 			if (i+1 >= sformat.length()) | ||||
| 				log_file_error(filename, linenum, "System task `%s' called with `%%' at end of string.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str()); | ||||
| 
 | ||||
| 			char cformat = sformat[++i]; | ||||
| 
 | ||||
|  | @ -77,13 +77,13 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg | |||
| 				case 'x': | ||||
| 				case 'X': | ||||
| 					if (next_arg >= GetSize(children)) | ||||
| 						log_file_error(filename, linenum, "Missing argument for %%%c format specifier in system task `%s'.\n", | ||||
| 						log_file_error(filename, location.first_line, "Missing argument for %%%c format specifier in system task `%s'.\n", | ||||
| 								cformat, str.c_str()); | ||||
| 
 | ||||
| 					node_arg = children[next_arg++]; | ||||
| 					while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 					if (node_arg->type != AST_CONSTANT) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); | ||||
| 					break; | ||||
| 
 | ||||
| 				case 'm': | ||||
|  | @ -91,7 +91,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg | |||
| 					break; | ||||
| 
 | ||||
| 				default: | ||||
| 					log_file_error(filename, linenum, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); | ||||
| 					break; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -159,7 +159,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 
 | ||||
| #if 0 | ||||
| 	log("-------------\n"); | ||||
| 	log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), linenum, type2str(type).c_str(), this); | ||||
| 	log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), location.first_line, type2str(type).c_str(), this); | ||||
| 	log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", | ||||
| 			int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); | ||||
| 	// dumpAst(NULL, "> ");
 | ||||
|  | @ -251,7 +251,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 						if (it.first != ID(mem2reg)) | ||||
| 							reg->attributes.emplace(it.first, it.second->clone()); | ||||
| 					reg->filename = node->filename; | ||||
| 					reg->linenum = node->linenum; | ||||
| 					reg->location = node->location; | ||||
| 					children.push_back(reg); | ||||
| 					while (reg->simplify(true, false, false, 1, -1, false, false)) { } | ||||
| 				} | ||||
|  | @ -273,7 +273,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	} | ||||
| 
 | ||||
| 	current_filename = filename; | ||||
| 	set_line_num(linenum); | ||||
| 
 | ||||
| 	// we do not look inside a task or function
 | ||||
| 	// (but as soon as a task or function is instantiated we process the generated AST as usual)
 | ||||
|  | @ -286,13 +285,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	// note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
 | ||||
| 	if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" || | ||||
| 			str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) { | ||||
| 		log_file_warning(filename, linenum, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); | ||||
| 		log_file_warning(filename, location.first_line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); | ||||
| 		delete_children(); | ||||
| 		str = std::string(); | ||||
| 	} | ||||
| 
 | ||||
| 	if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) { | ||||
| 		log_file_warning(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str()); | ||||
| 		log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); | ||||
| 		delete_children(); | ||||
| 		str = std::string(); | ||||
| 	} | ||||
|  | @ -304,14 +303,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	{ | ||||
| 		int nargs = GetSize(children); | ||||
| 		if (nargs < 1) | ||||
| 			log_file_error(filename, linenum, "System task `%s' got %d arguments, expected >= 1.\n", | ||||
| 			log_file_error(filename, location.first_line, "System task `%s' got %d arguments, expected >= 1.\n", | ||||
| 					str.c_str(), int(children.size())); | ||||
| 
 | ||||
| 		// First argument is the format string
 | ||||
| 		AstNode *node_string = children[0]; | ||||
| 		while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 		if (node_string->type != AST_CONSTANT) | ||||
| 			log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 			log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 		std::string sformat = node_string->bitsAsConst().decode_string(); | ||||
| 		std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); | ||||
| 		// Finally, print the message (only include a \n for $display, not for $write)
 | ||||
|  | @ -405,7 +404,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 					continue; | ||||
| 				wires_are_incompatible: | ||||
| 					if (stage > 1) | ||||
| 						log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", node->str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str()); | ||||
| 					continue; | ||||
| 				} | ||||
| 				this_wire_scope[node->str] = node; | ||||
|  | @ -451,7 +450,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_ALWAYS || type == AST_INITIAL) | ||||
| 	{ | ||||
| 		if (current_always != nullptr) | ||||
| 			log_file_error(filename, linenum, "Invalid nesting of always blocks and/or initializations.\n"); | ||||
| 			log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n"); | ||||
| 
 | ||||
| 		current_always = this; | ||||
| 		current_always_clocked = false; | ||||
|  | @ -494,7 +493,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic) | ||||
| 				children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment
 | ||||
| 			if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg) | ||||
| 				log_warning("wire '%s' is assigned in a block at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum); | ||||
| 				log_warning("wire '%s' is assigned in a block at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); | ||||
| 			if (type == AST_ASSIGN && children[0]->id2ast->is_reg) { | ||||
| 				bool is_rand_reg = false; | ||||
| 				if (children[1]->type == AST_FCALL) { | ||||
|  | @ -508,7 +507,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 						is_rand_reg = true; | ||||
| 				} | ||||
| 				if (!is_rand_reg) | ||||
| 					log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum); | ||||
| 					log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); | ||||
| 			} | ||||
| 			children[0]->was_checked = true; | ||||
| 		} | ||||
|  | @ -535,7 +534,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) | ||||
| 				did_something = true; | ||||
| 			if (!children[1]->range_valid) | ||||
| 				log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n"); | ||||
| 			width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); | ||||
| 		} | ||||
| 		break; | ||||
|  | @ -547,7 +546,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param)) | ||||
| 				did_something = true; | ||||
| 			if (!children[1]->range_valid) | ||||
| 				log_file_error(filename, linenum, "Non-constant width range on enum item decl.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n"); | ||||
| 			width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); | ||||
| 		} | ||||
| 		break; | ||||
|  | @ -786,7 +785,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	} | ||||
| 
 | ||||
| 	current_filename = filename; | ||||
| 	set_line_num(linenum); | ||||
| 
 | ||||
| 	if (type == AST_MODULE) | ||||
| 		current_scope.clear(); | ||||
|  | @ -795,7 +793,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_DEFPARAM && !children.empty()) | ||||
| 	{ | ||||
| 		if (children[0]->type != AST_IDENTIFIER) | ||||
| 			log_file_error(filename, linenum, "Module name in defparam contains non-constant expressions!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n"); | ||||
| 
 | ||||
| 		string modname, paramname = children[0]->str; | ||||
| 
 | ||||
|  | @ -812,12 +810,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		} | ||||
| 
 | ||||
| 		if (pos == std::string::npos) | ||||
| 			log_file_error(filename, linenum, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str()); | ||||
| 			log_file_error(filename, location.first_line, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str()); | ||||
| 
 | ||||
| 		paramname = "\\" + paramname.substr(pos+1); | ||||
| 
 | ||||
| 		if (current_scope.at(modname)->type != AST_CELL) | ||||
| 			log_file_error(filename, linenum, "Defparam argument `%s . %s` does not match a cell!\n", | ||||
| 			log_file_error(filename, location.first_line, "Defparam argument `%s . %s` does not match a cell!\n", | ||||
| 					RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str()); | ||||
| 
 | ||||
| 		AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL); | ||||
|  | @ -843,10 +841,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			log_assert(children.size() >= 1); | ||||
| 			log_assert(children[0]->type == AST_WIRETYPE); | ||||
| 			if (!current_scope.count(children[0]->str)) | ||||
| 				log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); | ||||
| 			AstNode *resolved_type = current_scope.at(children[0]->str); | ||||
| 			if (resolved_type->type != AST_TYPEDEF) | ||||
| 				log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[0]->str.c_str()); | ||||
| 			log_assert(resolved_type->children.size() == 1); | ||||
| 			AstNode *templ = resolved_type->children[0]; | ||||
| 			// Remove type reference
 | ||||
|  | @ -949,10 +947,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			log_assert(children.size() == 2); | ||||
| 			log_assert(children[1]->type == AST_WIRETYPE); | ||||
| 			if (!current_scope.count(children[1]->str)) | ||||
| 				log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str()); | ||||
| 			AstNode *resolved_type = current_scope.at(children[1]->str); | ||||
| 			if (resolved_type->type != AST_TYPEDEF) | ||||
| 				log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[1]->str.c_str()); | ||||
| 			log_assert(resolved_type->children.size() == 1); | ||||
| 			AstNode *templ = resolved_type->children[0]; | ||||
| 			delete children[1]; | ||||
|  | @ -962,7 +960,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | ||||
| 
 | ||||
| 			if (templ->type == AST_MEMORY) | ||||
| 				log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); | ||||
| 			is_signed = templ->is_signed; | ||||
| 			is_string = templ->is_string; | ||||
| 			is_custom_type = templ->is_custom_type; | ||||
|  | @ -983,7 +981,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_PREFIX) { | ||||
| 		if (children[0]->type != AST_CONSTANT) { | ||||
| 			// dumpAst(NULL, ">   ");
 | ||||
| 			log_file_error(filename, linenum, "Index in generate block prefix syntax is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Index in generate block prefix syntax is not constant!\n"); | ||||
| 		} | ||||
| 		if (children[1]->type == AST_PREFIX) | ||||
| 			children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param); | ||||
|  | @ -999,9 +997,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	// evaluate TO_BITS nodes
 | ||||
| 	if (type == AST_TO_BITS) { | ||||
| 		if (children[0]->type != AST_CONSTANT) | ||||
| 			log_file_error(filename, linenum, "Left operand of to_bits expression is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n"); | ||||
| 		if (children[1]->type != AST_CONSTANT) | ||||
| 			log_file_error(filename, linenum, "Right operand of to_bits expression is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Right operand of to_bits expression is not constant!\n"); | ||||
| 		RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed); | ||||
| 		newNode = mkconst_bits(new_value.bits, children[1]->is_signed); | ||||
| 		goto apply_newNode; | ||||
|  | @ -1065,7 +1063,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		multirange_dimensions.clear(); | ||||
| 		for (auto range : children[1]->children) { | ||||
| 			if (!range->range_valid) | ||||
| 				log_file_error(filename, linenum, "Non-constant range on memory decl.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n"); | ||||
| 			multirange_dimensions.push_back(min(range->range_left, range->range_right)); | ||||
| 			multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1); | ||||
| 			total_size *= multirange_dimensions.back(); | ||||
|  | @ -1083,7 +1081,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++) | ||||
| 		{ | ||||
| 			if (GetSize(children[0]->children) < i) | ||||
| 				log_file_error(filename, linenum, "Insufficient number of array indices for %s.\n", log_id(str)); | ||||
| 				log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str)); | ||||
| 
 | ||||
| 			AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); | ||||
| 
 | ||||
|  | @ -1112,11 +1110,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) { | ||||
| 		if (children.size() > 1 && children[1]->type == AST_RANGE) { | ||||
| 			if (!children[1]->range_valid) | ||||
| 				log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n"); | ||||
| 			int width = std::abs(children[1]->range_left - children[1]->range_right) + 1; | ||||
| 			if (children[0]->type == AST_REALVALUE) { | ||||
| 				RTLIL::Const constvalue = children[0]->realAsConst(width); | ||||
| 				log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", | ||||
| 				log_file_warning(filename, location.first_line, "converting real value %e to binary %s.\n", | ||||
| 						children[0]->realvalue, log_signal(constvalue)); | ||||
| 				delete children[0]; | ||||
| 				children[0] = mkconst_bits(constvalue.bits, sign_hint); | ||||
|  | @ -1190,7 +1188,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 				current_scope[str] = auto_wire; | ||||
| 				did_something = true; | ||||
| 			} else { | ||||
| 				log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); | ||||
| 			} | ||||
| 		} | ||||
| 		if (id2ast != current_scope[str]) { | ||||
|  | @ -1203,7 +1201,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue) | ||||
| 	{ | ||||
| 		if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) | ||||
| 			log_file_error(filename, linenum, "Invalid bit-select on memory access!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n"); | ||||
| 
 | ||||
| 		int mem_width, mem_size, addr_bits; | ||||
| 		id2ast->meminfo(mem_width, mem_size, addr_bits); | ||||
|  | @ -1215,7 +1213,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			std::swap(data_range_left, data_range_right); | ||||
| 
 | ||||
| 		std::stringstream sstr; | ||||
| 		sstr << "$mem2bits$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 		sstr << "$mem2bits$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 		std::string wire_id = sstr.str(); | ||||
| 
 | ||||
| 		AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true))); | ||||
|  | @ -1256,7 +1254,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	} | ||||
| 
 | ||||
| 	if (type == AST_WHILE) | ||||
| 		log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n"); | ||||
| 		log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n"); | ||||
| 
 | ||||
| 	if (type == AST_REPEAT) | ||||
| 	{ | ||||
|  | @ -1267,7 +1265,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		while (count->simplify(true, false, false, stage, 32, true, false)) { } | ||||
| 
 | ||||
| 		if (count->type != AST_CONSTANT) | ||||
| 			log_file_error(filename, linenum, "Repeat loops outside must have constant repeat counts!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n"); | ||||
| 
 | ||||
| 		// convert to a block with the body repeated n times
 | ||||
| 		type = AST_BLOCK; | ||||
|  | @ -1293,24 +1291,24 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			body_ast = body_ast->children.at(0); | ||||
| 
 | ||||
| 		if (init_ast->type != AST_ASSIGN_EQ) | ||||
| 			log_file_error(filename, linenum, "Unsupported 1st expression of generate for-loop!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Unsupported 1st expression of generate for-loop!\n"); | ||||
| 		if (next_ast->type != AST_ASSIGN_EQ) | ||||
| 			log_file_error(filename, linenum, "Unsupported 3rd expression of generate for-loop!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Unsupported 3rd expression of generate for-loop!\n"); | ||||
| 
 | ||||
| 		if (type == AST_GENFOR) { | ||||
| 			if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR) | ||||
| 				log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a gen var!\n"); | ||||
| 				log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a gen var!\n"); | ||||
| 			if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR) | ||||
| 				log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n"); | ||||
| 				log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n"); | ||||
| 		} else { | ||||
| 			if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE) | ||||
| 				log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a register!\n"); | ||||
| 				log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a register!\n"); | ||||
| 			if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE) | ||||
| 				log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a register!\n"); | ||||
| 				log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a register!\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast) | ||||
| 			log_file_error(filename, linenum, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n"); | ||||
| 
 | ||||
| 		// eval 1st expression
 | ||||
| 		AstNode *varbuf = init_ast->children[1]->clone(); | ||||
|  | @ -1322,7 +1320,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		} | ||||
| 
 | ||||
| 		if (varbuf->type != AST_CONSTANT) | ||||
| 			log_file_error(filename, linenum, "Right hand side of 1st expression of generate for-loop is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Right hand side of 1st expression of generate for-loop is not constant!\n"); | ||||
| 
 | ||||
| 		auto resolved = current_scope.at(init_ast->children[0]->str); | ||||
| 		if (resolved->range_valid) { | ||||
|  | @ -1363,7 +1361,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			} | ||||
| 
 | ||||
| 			if (buf->type != AST_CONSTANT) | ||||
| 				log_file_error(filename, linenum, "2nd expression of generate for-loop is not constant!\n"); | ||||
| 				log_file_error(filename, location.first_line, "2nd expression of generate for-loop is not constant!\n"); | ||||
| 
 | ||||
| 			if (buf->integer == 0) { | ||||
| 				delete buf; | ||||
|  | @ -1379,7 +1377,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 				buf = new AstNode(AST_GENBLOCK, body_ast->clone()); | ||||
| 			if (buf->str.empty()) { | ||||
| 				std::stringstream sstr; | ||||
| 				sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 				sstr << "$genblock$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 				buf->str = sstr.str(); | ||||
| 			} | ||||
| 			std::map<std::string, std::string> name_map; | ||||
|  | @ -1409,7 +1407,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			} | ||||
| 
 | ||||
| 			if (buf->type != AST_CONSTANT) | ||||
| 				log_file_error(filename, linenum, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str()); | ||||
| 
 | ||||
| 			delete varbuf->children[0]; | ||||
| 			varbuf->children[0] = buf; | ||||
|  | @ -1433,7 +1431,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	{ | ||||
| 		for (size_t i = 0; i < children.size(); i++) | ||||
| 			if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) | ||||
| 				log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); | ||||
| 				log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	// transform block with name
 | ||||
|  | @ -1481,7 +1479,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		if (buf->type != AST_CONSTANT) { | ||||
| 			// for (auto f : log_files)
 | ||||
| 			// 	dumpAst(f, "verilog-ast> ");
 | ||||
| 			log_file_error(filename, linenum, "Condition for generate if is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n"); | ||||
| 		} | ||||
| 		if (buf->asBool() != 0) { | ||||
| 			delete buf; | ||||
|  | @ -1522,7 +1520,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		if (buf->type != AST_CONSTANT) { | ||||
| 			// for (auto f : log_files)
 | ||||
| 			// 	dumpAst(f, "verilog-ast> ");
 | ||||
| 			log_file_error(filename, linenum, "Condition for generate case is not constant!\n"); | ||||
| 			log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		bool ref_signed = buf->is_signed; | ||||
|  | @ -1556,7 +1554,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 				if (buf->type != AST_CONSTANT) { | ||||
| 					// for (auto f : log_files)
 | ||||
| 					// 	dumpAst(f, "verilog-ast> ");
 | ||||
| 					log_file_error(filename, linenum, "Expression in generate case is not constant!\n"); | ||||
| 					log_file_error(filename, location.first_line, "Expression in generate case is not constant!\n"); | ||||
| 				} | ||||
| 
 | ||||
| 				bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool(); | ||||
|  | @ -1597,7 +1595,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_CELLARRAY) | ||||
| 	{ | ||||
| 		if (!children.at(0)->range_valid) | ||||
| 			log_file_error(filename, linenum, "Non-constant array range on cell array.\n"); | ||||
| 			log_file_error(filename, location.first_line, "Non-constant array range on cell array.\n"); | ||||
| 
 | ||||
| 		newNode = new AstNode(AST_GENBLOCK); | ||||
| 		int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1; | ||||
|  | @ -1608,7 +1606,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			newNode->children.push_back(new_cell); | ||||
| 			new_cell->str += stringf("[%d]", idx); | ||||
| 			if (new_cell->type == AST_PRIMITIVE) { | ||||
| 				log_file_error(filename, linenum, "Cell arrays of primitives are currently not supported.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Cell arrays of primitives are currently not supported.\n"); | ||||
| 			} else { | ||||
| 				log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); | ||||
| 				new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str()); | ||||
|  | @ -1622,7 +1620,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_PRIMITIVE) | ||||
| 	{ | ||||
| 		if (children.size() < 2) | ||||
| 			log_file_error(filename, linenum, "Insufficient number of arguments for primitive `%s'!\n", str.c_str()); | ||||
| 			log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str()); | ||||
| 
 | ||||
| 		std::vector<AstNode*> children_list; | ||||
| 		for (auto child : children) { | ||||
|  | @ -1637,7 +1635,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1") | ||||
| 		{ | ||||
| 			if (children_list.size() != 3) | ||||
| 				log_file_error(filename, linenum, "Invalid number of arguments for primitive `%s'!\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str()); | ||||
| 
 | ||||
| 			std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz); | ||||
| 
 | ||||
|  | @ -1724,7 +1722,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } | ||||
| 			while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } | ||||
| 			if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) | ||||
| 				log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); | ||||
| 			result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; | ||||
| 		} | ||||
| 		did_something = true; | ||||
|  | @ -1746,7 +1744,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 	if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL) | ||||
| 	{ | ||||
| 		std::stringstream sstr; | ||||
| 		sstr << "$formal$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 		sstr << "$formal$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 		std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN"; | ||||
| 
 | ||||
| 		AstNode *wire_check = new AstNode(AST_WIRE); | ||||
|  | @ -1854,7 +1852,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			newNode = new AstNode(AST_BLOCK); | ||||
| 
 | ||||
| 			AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true))); | ||||
| 			wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), linenum, autoidx++); | ||||
| 			wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++); | ||||
| 			current_ast_mod->children.push_back(wire_tmp); | ||||
| 			current_scope[wire_tmp->str] = wire_tmp; | ||||
| 			wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false); | ||||
|  | @ -1892,7 +1890,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			(children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE) | ||||
| 	{ | ||||
| 		std::stringstream sstr; | ||||
| 		sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 		sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 		std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; | ||||
| 
 | ||||
| 		int mem_width, mem_size, addr_bits; | ||||
|  | @ -2003,7 +2001,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } | ||||
| 				while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } | ||||
| 				if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) | ||||
| 					log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); | ||||
| 				int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; | ||||
| 
 | ||||
| 				assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), | ||||
|  | @ -2099,11 +2097,11 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				int num_steps = 1; | ||||
| 
 | ||||
| 				if (GetSize(children) != 1 && GetSize(children) != 2) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				if (!current_always_clocked) | ||||
| 					log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", | ||||
| 							RTLIL::unescape_id(str).c_str()); | ||||
| 
 | ||||
| 				if (GetSize(children) == 2) | ||||
|  | @ -2111,7 +2109,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					AstNode *buf = children[1]->clone(); | ||||
| 					while (buf->simplify(true, false, false, stage, -1, false, false)) { } | ||||
| 					if (buf->type != AST_CONSTANT) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); | ||||
| 
 | ||||
| 					num_steps = buf->asInt(true); | ||||
| 					delete buf; | ||||
|  | @ -2138,7 +2136,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE, | ||||
| 							mkconst_int(width_hint-1, true), mkconst_int(0, true))); | ||||
| 
 | ||||
| 					reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), linenum, myidx, i); | ||||
| 					reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), location.first_line, myidx, i); | ||||
| 					reg->is_reg = true; | ||||
| 
 | ||||
| 					current_ast_mod->children.push_back(reg); | ||||
|  | @ -2173,11 +2171,11 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed") | ||||
| 			{ | ||||
| 				if (GetSize(children) != 1) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				if (!current_always_clocked) | ||||
| 					log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", | ||||
| 							RTLIL::unescape_id(str).c_str()); | ||||
| 
 | ||||
| 				AstNode *present = children.at(0)->clone(); | ||||
|  | @ -2215,13 +2213,13 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			if (str == "\\$clog2") | ||||
| 			{ | ||||
| 				if (children.size() != 1) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				AstNode *buf = children[0]->clone(); | ||||
| 				while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 				if (buf->type != AST_CONSTANT) | ||||
| 					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); | ||||
| 
 | ||||
| 				RTLIL::Const arg_value = buf->bitsAsConst(); | ||||
| 				if (arg_value.as_bool()) | ||||
|  | @ -2240,11 +2238,11 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			if (str == "\\$size" || str == "\\$bits") | ||||
| 			{ | ||||
| 				if (str == "\\$bits" && children.size() != 1) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				if (str == "\\$size" && children.size() != 1 && children.size() != 2) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				int dim = 1; | ||||
|  | @ -2268,7 +2266,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					if (id_ast == NULL && current_scope.count(buf->str)) | ||||
| 						id_ast = current_scope.at(buf->str); | ||||
| 					if (!id_ast) | ||||
| 						log_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); | ||||
| 					if (id_ast->type == AST_MEMORY) { | ||||
| 						// We got here only if the argument is a memory
 | ||||
| 						// Otherwise $size() and $bits() return the expression width
 | ||||
|  | @ -2276,15 +2274,15 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 						if (str == "\\$bits") { | ||||
| 							if (mem_range->type == AST_RANGE) { | ||||
| 								if (!mem_range->range_valid) | ||||
| 									log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); | ||||
| 									log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); | ||||
| 								mem_depth = mem_range->range_left - mem_range->range_right + 1; | ||||
| 							} else | ||||
| 								log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); | ||||
| 								log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); | ||||
| 						} else { | ||||
| 							// $size()
 | ||||
| 							if (mem_range->type == AST_RANGE) { | ||||
| 								if (!mem_range->range_valid) | ||||
| 									log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); | ||||
| 									log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); | ||||
| 								int dims; | ||||
| 								if (id_ast->multirange_dimensions.empty()) | ||||
| 									dims = 1; | ||||
|  | @ -2295,9 +2293,9 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 								else if (dim <= dims) { | ||||
| 									width_hint = id_ast->multirange_dimensions[2*dim-1]; | ||||
| 								} else if ((dim > dims+1) || (dim < 0)) | ||||
| 									log_file_error(filename, linenum, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); | ||||
| 									log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); | ||||
| 							} else | ||||
| 								log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); | ||||
| 								log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | @ -2318,18 +2316,18 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 
 | ||||
| 				if (func_with_two_arguments) { | ||||
| 					if (children.size() != 2) | ||||
| 						log_file_error(filename, linenum, "System function %s got %d arguments, expected 2.\n", | ||||
| 						log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n", | ||||
| 								RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 				} else { | ||||
| 					if (children.size() != 1) | ||||
| 						log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", | ||||
| 						log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", | ||||
| 								RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 				} | ||||
| 
 | ||||
| 				if (children.size() >= 1) { | ||||
| 					while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 					if (!children[0]->isConst()) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n", | ||||
| 								RTLIL::unescape_id(str).c_str()); | ||||
| 					int child_width_hint = width_hint; | ||||
| 					bool child_sign_hint = sign_hint; | ||||
|  | @ -2340,7 +2338,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				if (children.size() >= 2) { | ||||
| 					while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 					if (!children[1]->isConst()) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n", | ||||
| 								RTLIL::unescape_id(str).c_str()); | ||||
| 					int child_width_hint = width_hint; | ||||
| 					bool child_sign_hint = sign_hint; | ||||
|  | @ -2383,7 +2381,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				AstNode *node_string = children[0]; | ||||
| 				while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 				if (node_string->type != AST_CONSTANT) | ||||
| 					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 				std::string sformat = node_string->bitsAsConst().decode_string(); | ||||
| 				std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); | ||||
| 				newNode = AstNode::mkconst_str(sout); | ||||
|  | @ -2404,14 +2402,14 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				for (int i = 2; i < GetSize(dpi_decl->children); i++) | ||||
| 				{ | ||||
| 					if (i-2 >= GetSize(children)) | ||||
| 						log_file_error(filename, linenum, "Insufficient number of arguments in DPI function call.\n"); | ||||
| 						log_file_error(filename, location.first_line, "Insufficient number of arguments in DPI function call.\n"); | ||||
| 
 | ||||
| 					argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); | ||||
| 					args.push_back(children.at(i-2)->clone()); | ||||
| 					while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } | ||||
| 
 | ||||
| 					if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate DPI function with non-constant argument.\n"); | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n"); | ||||
| 				} | ||||
| 
 | ||||
| 				newNode = dpi_call(rtype, fname, argtypes, args); | ||||
|  | @ -2423,7 +2421,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			} | ||||
| 
 | ||||
| 			if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) | ||||
| 				log_file_error(filename, linenum, "Can't resolve function name `%s'.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str()); | ||||
| 		} | ||||
| 
 | ||||
| 		if (type == AST_TCALL) | ||||
|  | @ -2431,26 +2429,26 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			if (str == "$finish" || str == "$stop") | ||||
| 			{ | ||||
| 				if (!current_always || current_always->type != AST_INITIAL) | ||||
| 					log_file_error(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); | ||||
| 
 | ||||
| 				log_file_error(filename, linenum, "System task `%s' executed.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str()); | ||||
| 			} | ||||
| 
 | ||||
| 			if (str == "\\$readmemh" || str == "\\$readmemb") | ||||
| 			{ | ||||
| 				if (GetSize(children) < 2 || GetSize(children) > 4) | ||||
| 					log_file_error(filename, linenum, "System function %s got %d arguments, expected 2-4.\n", | ||||
| 					log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2-4.\n", | ||||
| 							RTLIL::unescape_id(str).c_str(), int(children.size())); | ||||
| 
 | ||||
| 				AstNode *node_filename = children[0]->clone(); | ||||
| 				while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 				if (node_filename->type != AST_CONSTANT) | ||||
| 					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); | ||||
| 
 | ||||
| 				AstNode *node_memory = children[1]->clone(); | ||||
| 				while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 				if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY) | ||||
| 					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); | ||||
| 
 | ||||
| 				int start_addr = -1, finish_addr = -1; | ||||
| 
 | ||||
|  | @ -2458,7 +2456,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					AstNode *node_addr = children[2]->clone(); | ||||
| 					while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 					if (node_addr->type != AST_CONSTANT) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); | ||||
| 					start_addr = int(node_addr->asInt(false)); | ||||
| 				} | ||||
| 
 | ||||
|  | @ -2466,7 +2464,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					AstNode *node_addr = children[3]->clone(); | ||||
| 					while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } | ||||
| 					if (node_addr->type != AST_CONSTANT) | ||||
| 						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); | ||||
| 						log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); | ||||
| 					finish_addr = int(node_addr->asInt(false)); | ||||
| 				} | ||||
| 
 | ||||
|  | @ -2494,13 +2492,13 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			} | ||||
| 
 | ||||
| 			if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK) | ||||
| 				log_file_error(filename, linenum, "Can't resolve task name `%s'.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str()); | ||||
| 		} | ||||
| 
 | ||||
| 		AstNode *decl = current_scope[str]; | ||||
| 
 | ||||
| 		std::stringstream sstr; | ||||
| 		sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; | ||||
| 		sstr << "$func$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++) << "$"; | ||||
| 		std::string prefix = sstr.str(); | ||||
| 
 | ||||
| 		bool recommend_const_eval = false; | ||||
|  | @ -2522,9 +2520,9 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			} | ||||
| 
 | ||||
| 			if (in_param) | ||||
| 				log_file_error(filename, linenum, "Non-constant function call in constant expression.\n"); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n"); | ||||
| 			if (require_const_eval) | ||||
| 				log_file_error(filename, linenum, "Function %s can only be called with constant arguments.\n", str.c_str()); | ||||
| 				log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str()); | ||||
| 		} | ||||
| 
 | ||||
| 		size_t arg_count = 0; | ||||
|  | @ -2646,7 +2644,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 									goto tcall_incompatible_wires; | ||||
| 						} else { | ||||
| 					tcall_incompatible_wires: | ||||
| 							log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", child->str.c_str()); | ||||
| 							log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str()); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | @ -3000,7 +2998,7 @@ apply_newNode: | |||
| 		// newNode->dumpAst(stderr, "+ ");
 | ||||
| 		log_assert(newNode != NULL); | ||||
| 		newNode->filename = filename; | ||||
| 		newNode->linenum = linenum; | ||||
| 		newNode->location = location; | ||||
| 		newNode->cloneInto(this); | ||||
| 		delete newNode; | ||||
| 		did_something = true; | ||||
|  | @ -3049,7 +3047,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m | |||
| 		yosys_input_files.insert(mem_filename); | ||||
| 	} | ||||
| 	if (f.fail() || GetSize(mem_filename) == 0) | ||||
| 		log_file_error(filename, linenum, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str()); | ||||
| 		log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str()); | ||||
| 
 | ||||
| 	log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid); | ||||
| 	int range_left =  memory->children[1]->range_left, range_right =  memory->children[1]->range_right; | ||||
|  | @ -3095,7 +3093,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m | |||
| 				char *endptr; | ||||
| 				cursor = strtol(nptr, &endptr, 16); | ||||
| 				if (!*nptr || *endptr) | ||||
| 					log_file_error(filename, linenum, "Can not parse address `%s` for %s.\n", nptr, str.c_str()); | ||||
| 					log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -3270,7 +3268,7 @@ static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> & | |||
| 	if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) { | ||||
| 		AstNode *mem = that->id2ast; | ||||
| 		if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS)) | ||||
| 			mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum)); | ||||
| 			mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->location.first_line)); | ||||
| 		mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS; | ||||
| 	} | ||||
| } | ||||
|  | @ -3298,14 +3296,14 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg | |||
| 			// activate mem2reg if this is assigned in an async proc
 | ||||
| 			if (flags & AstNode::MEM2REG_FL_ASYNC) { | ||||
| 				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC)) | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); | ||||
| 				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC; | ||||
| 			} | ||||
| 
 | ||||
| 			// remember if this is assigned blocking (=)
 | ||||
| 			if (type == AST_ASSIGN_EQ) { | ||||
| 				if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1)) | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); | ||||
| 				proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -3322,11 +3320,11 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg | |||
| 			// remember where this is
 | ||||
| 			if (flags & MEM2REG_FL_INIT) { | ||||
| 				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT)) | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); | ||||
| 				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT; | ||||
| 			} else { | ||||
| 				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE)) | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); | ||||
| 					mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); | ||||
| 				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -3340,7 +3338,7 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg | |||
| 
 | ||||
| 		// flag if used after blocking assignment (in same proc)
 | ||||
| 		if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) { | ||||
| 			mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); | ||||
| 			mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); | ||||
| 			mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -3409,7 +3407,7 @@ bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set) | |||
| 		return false; | ||||
| 
 | ||||
| 	if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1) | ||||
| 		log_file_error(filename, linenum, "Invalid array access.\n"); | ||||
| 		log_file_error(filename, location.first_line, "Invalid array access.\n"); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
|  | @ -3501,7 +3499,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, | |||
| 			children[0]->children[0]->children[0]->type != AST_CONSTANT) | ||||
| 	{ | ||||
| 		std::stringstream sstr; | ||||
| 		sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 		sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 		std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; | ||||
| 
 | ||||
| 		int mem_width, mem_size, addr_bits; | ||||
|  | @ -3580,7 +3578,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, | |||
| 		else | ||||
| 		{ | ||||
| 			std::stringstream sstr; | ||||
| 			sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); | ||||
| 			sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); | ||||
| 			std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; | ||||
| 
 | ||||
| 			int mem_width, mem_size, addr_bits; | ||||
|  | @ -3724,13 +3722,13 @@ void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia | |||
| 		int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); | ||||
| 		if (!children.empty()) { | ||||
| 			if (children.size() != 1 || children.at(0)->type != AST_RANGE) | ||||
| 				log_file_error(filename, linenum, "Memory access in constant function is not supported\n%s:%d: ...called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s:%d.%d-%d.%d: ...called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 			children.at(0)->replace_variables(variables, fcall); | ||||
| 			while (simplify(true, false, false, 1, -1, false, true)) { } | ||||
| 			if (!children.at(0)->range_valid) | ||||
| 				log_file_error(filename, linenum, "Non-constant range\n%s:%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(filename, location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 			offset = min(children.at(0)->range_left, children.at(0)->range_right); | ||||
| 			width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width); | ||||
| 		} | ||||
|  | @ -3761,8 +3759,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 		{ | ||||
| 			while (child->simplify(true, false, false, 1, -1, false, true)) { } | ||||
| 			if (!child->range_valid) | ||||
| 				log_file_error(child->filename, child->linenum, "Can't determine size of variable %s\n%s:%d: ... called from here.\n", | ||||
| 						child->str.c_str(), fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(child->filename, child->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						child->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 			variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1); | ||||
| 			variables[child->str].offset = min(child->range_left, child->range_right); | ||||
| 			variables[child->str].is_signed = child->is_signed; | ||||
|  | @ -3801,24 +3799,24 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 				continue; | ||||
| 
 | ||||
| 			if (stmt->children.at(1)->type != AST_CONSTANT) | ||||
| 				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here. X\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here. X\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 			if (stmt->children.at(0)->type != AST_IDENTIFIER) | ||||
| 				log_file_error(stmt->filename, stmt->linenum, "Unsupported composite left hand side in constant function\n%s:%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 			if (!variables.count(stmt->children.at(0)->str)) | ||||
| 				log_file_error(stmt->filename, stmt->linenum, "Assignment to non-local variable in constant function\n%s:%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 			if (stmt->children.at(0)->children.empty()) { | ||||
| 				variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); | ||||
| 			} else { | ||||
| 				AstNode *range = stmt->children.at(0)->children.at(0); | ||||
| 				if (!range->range_valid) | ||||
| 					log_file_error(range->filename, range->linenum, "Non-constant range\n%s:%d: ... called from here.\n", | ||||
| 							fcall->filename.c_str(), fcall->linenum); | ||||
| 					log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 							fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 				int offset = min(range->range_left, range->range_right); | ||||
| 				int width = std::abs(range->range_left - range->range_right) + 1; | ||||
| 				varinfo_t &v = variables[stmt->children.at(0)->str]; | ||||
|  | @ -3849,8 +3847,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 			while (cond->simplify(true, false, false, 1, -1, false, true)) { } | ||||
| 
 | ||||
| 			if (cond->type != AST_CONSTANT) | ||||
| 				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 			if (cond->asBool()) { | ||||
| 				block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); | ||||
|  | @ -3870,8 +3868,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 			while (num->simplify(true, false, false, 1, -1, false, true)) { } | ||||
| 
 | ||||
| 			if (num->type != AST_CONSTANT) | ||||
| 				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->linenum); | ||||
| 				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 						fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 			block->children.erase(block->children.begin()); | ||||
| 			for (int i = 0; i < num->bitsAsConst().as_int(); i++) | ||||
|  | @ -3908,8 +3906,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 					while (cond->simplify(true, false, false, 1, -1, false, true)) { } | ||||
| 
 | ||||
| 					if (cond->type != AST_CONSTANT) | ||||
| 						log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", | ||||
| 								fcall->filename.c_str(), fcall->linenum); | ||||
| 						log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 								fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 
 | ||||
| 					found_match = cond->asBool(); | ||||
| 					delete cond; | ||||
|  | @ -3938,8 +3936,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) | |||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		log_file_error(stmt->filename, stmt->linenum, "Unsupported language construct in constant function\n%s:%d: ... called from here.\n", | ||||
| 				fcall->filename.c_str(), fcall->linenum); | ||||
| 		log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", | ||||
| 				fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); | ||||
| 		log_abort(); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue