From 81e52704846e77d0badcde06a10eac6eac42fba8 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 18 Jun 2025 22:50:46 +0200 Subject: [PATCH] ast, read_verilog: unify location types, reduce filename copying --- frontends/ast/ast.cc | 37 +- frontends/ast/ast.h | 11 +- frontends/ast/genrtlil.cc | 67 +-- frontends/ast/simplify.cc | 562 +++++++++++----------- frontends/verilog/.gitignore | 2 - frontends/verilog/Makefile.inc | 4 +- frontends/verilog/const2ast.cc | 2 +- frontends/verilog/verilog_frontend.cc | 25 +- frontends/verilog/verilog_lexer.h | 6 +- frontends/verilog/verilog_lexer.l | 38 +- frontends/verilog/verilog_parser.y | 650 +++++++++++++------------- kernel/rtlil.cc | 4 +- 12 files changed, 715 insertions(+), 693 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 28a6fce99..92f5fafdd 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -207,7 +207,7 @@ AstNode::AstNode(AstSrcLocType loc, AstNodeType type, std::unique_ptr c astnodes++; this->type = type; - loc = loc; + location = loc; is_input = false; is_output = false; is_reg = false; @@ -921,7 +921,7 @@ std::unique_ptr AstNode::mktemp_logic(AstSrcLocType loc, const std::str { auto wire_owned = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, mkconst_int(loc, range_left, true), mkconst_int(loc, range_right, true))); auto* wire = wire_owned.get(); - wire->str = stringf("%s%s:%d$%d", name.c_str(), RTLIL::encode_filename(location.filename).c_str(), location.first_line, autoidx++); + wire->str = stringf("%s%s:%d$%d", name.c_str(), RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line, autoidx++); if (nosync) wire->set_attribute(ID::nosync, AstNode::mkconst_int(loc, 1, false)); wire->is_signed = is_signed; @@ -1085,7 +1085,7 @@ RTLIL::Const AstNode::realAsConst(int width) std::string AstNode::loc_string() const { - return stringf("%s:%d.%d-%d.%d", location.filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + return stringf("%s:%d.%d-%d.%d", location.begin.filename->c_str(), location.begin.line, location.begin.column, location.end.line, location.end.column); } void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast) @@ -1246,7 +1246,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d ast->children.swap(new_children); if (ast->attributes.count(ID::blackbox) == 0) { - ast->set_attribute(ID::blackbox, AstNode::mkconst_int(1, false)); + ast->set_attribute(ID::blackbox, AstNode::mkconst_int(ast->location, 1, false)); } } @@ -1443,7 +1443,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump if (design->has(child->str)) { RTLIL::Module *existing_mod = design->module(child->str); if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { - log_file_error(child->location.filename, child->location.first_line, "Re-definition of module `%s'!\n", child->str.c_str()); + log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str.c_str()); } else if (nooverwrite) { log("Ignoring re-definition of module `%s' at %s.\n", child->str.c_str(), child->loc_string().c_str()); @@ -1526,7 +1526,8 @@ AstNode * AST::find_modport(AstNode *intf, std::string name) void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport) { for (auto w : intfmodule->wires()){ - auto wire = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true))); + auto loc = module_ast->location; + auto wire = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); std::string origname = log_id(w->name); std::string newname = intfname + "." + origname; wire->str = newname; @@ -1583,11 +1584,12 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dictclone(); + auto loc = ast->location; for (auto &intf : local_interfaces) { std::string intfname = intf.first.str(); RTLIL::Module *intfmodule = intf.second; for (auto w : intfmodule->wires()){ - auto wire = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true))); + auto wire = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); std::string newname = log_id(w->name); newname = intfname + "." + newname; wire->str = newname; @@ -1615,9 +1617,9 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dictmodule(interface_type) != nullptr) { // Add a cell to the module corresponding to the interface port such that // it can further propagated down if needed: - auto celltype_for_intf = std::make_unique(AST_CELLTYPE); + auto celltype_for_intf = std::make_unique(loc, AST_CELLTYPE); celltype_for_intf->str = interface_type; - auto cell_for_intf = std::make_unique(AST_CELL, std::move(celltype_for_intf)); + auto cell_for_intf = std::make_unique(loc, AST_CELL, std::move(celltype_for_intf)); cell_for_intf->str = name_port + "_inst_from_top_dummy"; new_ast->children.push_back(std::move(cell_for_intf)); @@ -1824,8 +1826,9 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictclone(); + auto loc = ast->location; if (!new_ast->attributes.count(ID::hdlname)) - new_ast->set_attribute(ID::hdlname, AstNode::mkconst_str(stripped_name.substr(1))); + new_ast->set_attribute(ID::hdlname, AstNode::mkconst_str(loc, stripped_name.substr(1))); para_counter = 0; for (auto& child : new_ast->children) { @@ -1849,12 +1852,12 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictchildren.insert(child->children.begin(), nullptr); if ((it->second.flags & RTLIL::CONST_FLAG_REAL) != 0) { - child->children[0] = std::make_unique(AST_REALVALUE); + child->children[0] = std::make_unique(loc, AST_REALVALUE); child->children[0]->realvalue = std::stod(it->second.decode_string()); } else if ((it->second.flags & RTLIL::CONST_FLAG_STRING) != 0) - child->children[0] = AstNode::mkconst_str(it->second.decode_string()); + child->children[0] = AstNode::mkconst_str(loc, it->second.decode_string()); else - child->children[0] = AstNode::mkconst_bits(it->second.to_bits(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0); + child->children[0] = AstNode::mkconst_bits(loc, it->second.to_bits(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0); rewritten.insert(it->first); } @@ -1862,12 +1865,12 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict(AST_DEFPARAM, std::make_unique(AST_IDENTIFIER)); + auto defparam = std::make_unique(loc, AST_DEFPARAM, std::make_unique(loc, AST_IDENTIFIER)); defparam->children[0]->str = param.first.str(); if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) - defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); + defparam->children.push_back(AstNode::mkconst_str(loc, param.second.decode_string())); else - defparam->children.push_back(AstNode::mkconst_bits(param.second.to_bits(), (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); + defparam->children.push_back(AstNode::mkconst_bits(loc, param.second.to_bits(), (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); new_ast->children.push_back(std::move(defparam)); } @@ -1922,7 +1925,7 @@ void AstNode::input_error(const char *format, ...) const { va_list ap; va_start(ap, format); - logv_file_error(location.filename, location.first_line, format, ap); + logv_file_error(*location.begin.filename, location.begin.line, format, ap); } YOSYS_NAMESPACE_END diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f881dfcb7..f4cbd4ad4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -28,6 +28,7 @@ #include "kernel/rtlil.h" #include "kernel/fmt.h" +#include "frontends/verilog/verilog_location.h" #include #include @@ -162,13 +163,7 @@ namespace AST AST_BIND }; - struct AstSrcLocType { - std::string filename; - unsigned int first_line, last_line; - unsigned int first_column, last_column; - AstSrcLocType() : filename(""), first_line(0), last_line(0), first_column(0), last_column(0) {} - AstSrcLocType(std::string _filename, int _first_line, int _first_column, int _last_line, int _last_column) : filename(_filename), first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {} - }; + using AstSrcLocType = location; // convert an node type to a string (e.g. for debug output) std::string type2str(AstNodeType type); @@ -407,7 +402,7 @@ namespace AST // this must be set by the language frontend before parsing the sources // the AstNode constructor then uses current_filename and get_line_num() // to initialize the filename and linenum properties of new nodes - extern std::string current_filename; + // extern std::string current_filename; // also set by the language frontend to control some AST processing extern bool sv_mode_but_global_and_used_for_literally_one_condition; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dadc4129f..2c2f8e1c4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -45,7 +45,7 @@ using namespace AST_INTERNAL; // helper function for creating RTLIL code for unary operations static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) { - IdString name = stringf("%s$%s:%d$%d", type.c_str(), RTLIL::encode_filename(that->location.filename).c_str(), that->location.first_line, autoidx++); + IdString name = stringf("%s$%s:%d$%d", type.c_str(), RTLIL::encode_filename(*that->location.begin.filename).c_str(), that->location.begin.line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, type); set_src_attr(cell, that); @@ -77,7 +77,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s return; } - IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(that->location.filename).c_str(), that->location.first_line, autoidx++); + IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(*that->location.begin.filename).c_str(), that->location.begin.line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, ID($pos)); set_src_attr(cell, that); @@ -104,7 +104,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s // helper function for creating RTLIL code for binary operations static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - IdString name = stringf("%s$%s:%d$%d", type.c_str(), RTLIL::encode_filename(that->location.filename).c_str(), that->location.first_line, autoidx++); + IdString name = stringf("%s$%s:%d$%d", type.c_str(), RTLIL::encode_filename(*that->location.begin.filename).c_str(), that->location.begin.line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, type); set_src_attr(cell, that); @@ -138,7 +138,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const log_assert(cond.size() == 1); std::stringstream sstr; - sstr << "$ternary$" << RTLIL::encode_filename(that->location.filename) << ":" << that->location.first_line << "$" << (autoidx++); + sstr << "$ternary$" << RTLIL::encode_filename(*that->location.begin.filename) << ":" << that->location.begin.line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($mux)); set_src_attr(cell, that); @@ -195,12 +195,12 @@ struct AST_INTERNAL::LookaheadRewriter if (node->lookahead) { log_assert(node->type == AST_IDENTIFIER); if (!lookaheadids.count(node->str)) { - auto wire = std::make_unique(AST_WIRE); + auto wire = std::make_unique(node->location, AST_WIRE); for (auto& c : node->id2ast->children) wire->children.push_back(c->clone()); wire->fixup_hierarchy_flags(); wire->str = stringf("$lookahead%s$%d", node->str.c_str(), autoidx++); - wire->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire->set_attribute(ID::nosync, AstNode::mkconst_int(node->location, 1, false)); wire->is_logic = true; while (wire->simplify(true, 1, -1, false)) { } lookaheadids[node->str] = make_pair(node->id2ast, wire.get()); @@ -271,6 +271,7 @@ struct AST_INTERNAL::LookaheadRewriter // top->dumpVlog(nullptr, "REWRITE-BEFORE> "); AstNode *block = nullptr; + auto loc = top->location; for (auto& c : top->children) if (c->type == AST_BLOCK) { @@ -284,18 +285,18 @@ struct AST_INTERNAL::LookaheadRewriter for (auto it : lookaheadids) { - auto ref_orig = std::make_unique(AST_IDENTIFIER); + auto ref_orig = std::make_unique(loc, AST_IDENTIFIER); ref_orig->str = it.second.first->str; ref_orig->id2ast = it.second.first; ref_orig->was_checked = true; - auto ref_temp = std::make_unique(AST_IDENTIFIER); + auto ref_temp = std::make_unique(loc, AST_IDENTIFIER); ref_temp->str = it.second.second->str; ref_temp->id2ast = it.second.second; ref_temp->was_checked = true; - auto init_assign = std::make_unique(AST_ASSIGN_EQ, ref_temp->clone(), ref_orig->clone()); - auto final_assign = std::make_unique(AST_ASSIGN_LE, std::move(ref_orig), std::move(ref_temp)); + auto init_assign = std::make_unique(loc, AST_ASSIGN_EQ, ref_temp->clone(), ref_orig->clone()); + auto final_assign = std::make_unique(loc, AST_ASSIGN_LE, std::move(ref_orig), std::move(ref_temp)); block->children.insert(block->children.begin(), std::move(init_assign)); block->children.push_back(std::move(final_assign)); @@ -347,7 +348,7 @@ struct AST_INTERNAL::ProcessGenerator LookaheadRewriter la_rewriter(always.get()); // generate process and simple root case - proc = current_module->addProcess(stringf("$proc$%s:%d$%d", RTLIL::encode_filename(always->location.filename).c_str(), always->location.first_line, autoidx++)); + proc = current_module->addProcess(stringf("$proc$%s:%d$%d", RTLIL::encode_filename(*always->location.begin.filename).c_str(), always->location.begin.line, autoidx++)); set_src_attr(proc, always.get()); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) @@ -723,7 +724,7 @@ struct AST_INTERNAL::ProcessGenerator if (ast->str == "$display" || ast->str == "$displayb" || ast->str == "$displayh" || ast->str == "$displayo" || ast->str == "$write" || ast->str == "$writeb" || ast->str == "$writeh" || ast->str == "$writeo") { std::stringstream sstr; - sstr << ast->str << "$" << ast->location.filename << ":" << ast->location.first_line << "$" << (autoidx++); + sstr << ast->str << "$" << ast->location.begin.filename << ":" << ast->location.begin.line << "$" << (autoidx++); Wire *en = current_module->addWire(sstr.str() + "_EN", 1); set_src_attr(en, ast); @@ -766,8 +767,8 @@ struct AST_INTERNAL::ProcessGenerator node->detectSignWidth(width, is_signed, nullptr); VerilogFmtArg arg = {}; - arg.filename = node->location.filename; - arg.first_line = node->location.first_line; + arg.filename = *node->location.begin.filename; + arg.first_line = node->location.begin.line; if (node->type == AST_CONSTANT && node->is_string) { arg.type = VerilogFmtArg::STRING; arg.str = node->bitsAsConst().decode_string(); @@ -793,7 +794,7 @@ struct AST_INTERNAL::ProcessGenerator fmt.append_literal("\n"); fmt.emit_rtlil(cell); } else if (!ast->str.empty()) { - log_file_error(ast->location.filename, ast->location.first_line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); + log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); } break; @@ -813,7 +814,7 @@ struct AST_INTERNAL::ProcessGenerator IdString cellname; if (ast->str.empty()) - cellname = stringf("$%s$%s:%d$%d", flavor.c_str(), RTLIL::encode_filename(ast->location.filename).c_str(), ast->location.first_line, autoidx++); + cellname = stringf("$%s$%s:%d$%d", flavor.c_str(), RTLIL::encode_filename(*ast->location.begin.filename).c_str(), ast->location.begin.line, autoidx++); else cellname = ast->str; check_unique_id(current_module, cellname, ast, "procedural assertion"); @@ -843,7 +844,7 @@ struct AST_INTERNAL::ProcessGenerator set_src_attr(cell, ast); for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->location.filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } cell->setParam(ID::FLAVOR, flavor); @@ -1503,7 +1504,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig = realAsConst(width_hint); - log_file_warning(location.filename, location.first_line, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); + log_file_warning(*location.begin.filename, location.begin.line, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); return sig; } @@ -1535,7 +1536,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (dynamic_cast(current_module)) { /* nothing to do here */ } else if (flag_autowire) - log_file_warning(location.filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str.c_str()); else input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); } @@ -1610,7 +1611,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("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; - auto fake_ast = std::make_unique(AST_NONE, clone(), children[0]->children.size() >= 2 ? + auto fake_ast = std::make_unique(children[0]->location, AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); if (member_node) @@ -1640,10 +1641,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk.offset = source_width - (chunk.offset + chunk.width); if (chunk.offset > chunk_left || chunk.offset + chunk.width < chunk_right) { if (chunk.width == 1) - log_file_warning(location.filename, location.first_line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", + log_file_warning(*location.begin.filename, location.begin.line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", str.c_str()); else - log_file_warning(location.filename, location.first_line, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n", + log_file_warning(*location.begin.filename, location.begin.line, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width); chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); } else { @@ -1657,10 +1658,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk.offset += add_undef_bits_lsb; } if (add_undef_bits_lsb) - log_file_warning(location.filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", + log_file_warning(*location.begin.filename, location.begin.line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb); if (add_undef_bits_msb) - log_file_warning(location.filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", + log_file_warning(*location.begin.filename, location.begin.line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb); } } @@ -1934,7 +1935,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMRD: { std::stringstream sstr; - sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($memrd)); set_src_attr(cell, this); @@ -1972,7 +1973,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMINIT: { std::stringstream sstr; - sstr << "$meminit$" << str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$meminit$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); SigSpec en_sig = children[2]->genRTLIL(); @@ -2017,7 +2018,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) IdString cellname; if (str.empty()) - cellname = stringf("$%s$%s:%d$%d", flavor.c_str(), RTLIL::encode_filename(location.filename).c_str(), location.first_line, autoidx++); + cellname = stringf("$%s$%s:%d$%d", flavor.c_str(), RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line, autoidx++); else cellname = str; check_unique_id(current_module, cellname, this, "procedural assertion"); @@ -2060,7 +2061,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) new_left.append(left[i]); new_right.append(right[i]); } - log_file_warning(location.filename, location.first_line, "Ignoring assignment to constant bits:\n" + log_file_warning(*location.begin.filename, location.begin.line, "Ignoring assignment to constant bits:\n" " old assignment: %s = %s\n new assignment: %s = %s.\n", log_signal(left), log_signal(right), log_signal(new_left), log_signal(new_right)); @@ -2095,7 +2096,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str; const AstNode *value = child->children[0].get(); if (value->type == AST_REALVALUE) - log_file_warning(location.filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n", + log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n", log_id(cell), log_id(paraname), value->realvalue); else if (value->type != AST_CONSTANT) input_error("Parameter %s.%s with non-constant value!\n", @@ -2192,14 +2193,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int sz = children.size(); if (str == "$info") { if (sz > 0) - log_file_info(location.filename, location.first_line, "%s.\n", children[0]->str.c_str()); + log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str()); else - log_file_info(location.filename, location.first_line, "\n"); + log_file_info(*location.begin.filename, location.begin.line, "\n"); } else if (str == "$warning") { if (sz > 0) - log_file_warning(location.filename, location.first_line, "%s.\n", children[0]->str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str()); else - log_file_warning(location.filename, location.first_line, "\n"); + log_file_warning(*location.begin.filename, location.begin.line, "\n"); } else if (str == "$error") { if (sz > 0) input_error("%s.\n", children[0]->str.c_str()); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 402dcb1e0..4b5cc178c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -155,8 +155,8 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_ while (node_arg->simplify(true, stage, -1, false)) { } VerilogFmtArg arg = {}; - arg.filename = location.filename; - arg.first_line = location.first_line; + arg.filename = *location.begin.filename; + arg.first_line = location.begin.line; if (node_arg->type == AST_CONSTANT && node_arg->is_string) { arg.type = VerilogFmtArg::STRING; arg.str = node_arg->bitsAsConst().decode_string(); @@ -173,10 +173,10 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_ arg.sig = node_arg->bitsAsConst(); arg.signed_ = node_arg->is_signed; } else if (may_fail) { - log_file_info(location.filename, location.first_line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); return Fmt(); } else { - log_file_error(location.filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); } args.push_back(arg); } @@ -424,12 +424,13 @@ static std::unique_ptr index_offset(std::unique_ptr offset, As stride /= decl_node->dimensions[dimension].range_width; auto right = normalize_index(rnode->children.back().get(), decl_node, dimension); auto add_offset = stride > 1 ? multiply_by_const(std::move(right), stride) : std::move(right); - return offset ? std::make_unique(AST_ADD, std::move(offset), std::move(add_offset)) : std::move(add_offset); + return offset ? std::make_unique(rnode->location, AST_ADD, std::move(offset), std::move(add_offset)) : std::move(add_offset); } static std::unique_ptr index_msb_offset(std::unique_ptr lsb_offset, AstNode *rnode, AstNode *decl_node, int dimension, int stride) { log_assert(rnode->children.size() <= 2); + auto loc = rnode->location; // Offset to add to LSB std::unique_ptr add_offset; @@ -442,15 +443,15 @@ static std::unique_ptr index_msb_offset(std::unique_ptr lsb_of // Slice, e.g. s.a[i:j] auto left = normalize_index(rnode->children[0].get(), decl_node, dimension); auto right = normalize_index(rnode->children[1].get(), decl_node, dimension); - add_offset = std::make_unique(AST_SUB, std::move(left), std::move(right)); + add_offset = std::make_unique(loc, AST_SUB, std::move(left), std::move(right)); if (stride > 1) { // offset = (msb - lsb + 1)*stride - 1 - auto slice_width = std::make_unique(AST_ADD, std::move(add_offset), node_int(1)); - add_offset = std::make_unique(AST_SUB, multiply_by_const(std::move(slice_width), stride), node_int(1)); + auto slice_width = std::make_unique(loc, AST_ADD, std::move(add_offset), node_int(loc, 1)); + add_offset = std::make_unique(loc, AST_SUB, multiply_by_const(std::move(slice_width), stride), node_int(loc, 1)); } } - return std::make_unique(AST_ADD, std::move(lsb_offset), std::move(add_offset)); + return std::make_unique(loc, AST_ADD, std::move(lsb_offset), std::move(add_offset)); } @@ -461,7 +462,7 @@ std::unique_ptr AstNode::make_index_range(AstNode *decl_node, bool unpa // such as array indexing or slicing if (children.empty()) { // no range operations apply, return the whole width - return make_range(decl_node->range_left - decl_node->range_right, 0); + return make_range(decl_node->location, decl_node->range_left - decl_node->range_right, 0); } log_assert(children.size() == 1); @@ -495,7 +496,7 @@ std::unique_ptr AstNode::make_index_range(AstNode *decl_node, bool unpa input_error("Unsupported range operation for %s\n", str.c_str()); } - std::unique_ptrindex_range = std::make_unique(AST_RANGE); + std::unique_ptr index_range = std::make_unique(rnode->location, AST_RANGE); if (!unpacked_range && (stride > 1 || GetSize(rnode->children) == 2)) { // Calculate MSB offset for the final index / slice of packed dimensions. @@ -537,7 +538,8 @@ static void add_members_to_scope(AstNode *snode, std::string name) std::unique_ptr make_packed_struct(AstNode *template_node, std::string &name, decltype(AstNode::attributes) &attributes) { // create a wire for the packed struct - auto wnode = std::make_unique(AST_WIRE, make_range(template_node->range_left, 0)); + auto loc = template_node->location; + auto wnode = std::make_unique(loc, AST_WIRE, make_range(loc, template_node->range_left, 0)); wnode->str = name; wnode->is_logic = true; wnode->range_valid = true; @@ -557,8 +559,9 @@ std::unique_ptr make_packed_struct(AstNode *template_node, std::string static void prepend_ranges(std::unique_ptr &range, AstNode *range_add) { // Convert range to multirange. + auto loc = range->location; if (range->type == AST_RANGE) - range = std::make_unique(AST_MULTIRANGE, std::move(range)); + range = std::make_unique(loc, AST_MULTIRANGE, std::move(range)); // Add range or ranges. if (range_add->type == AST_RANGE) @@ -693,15 +696,15 @@ static bool contains_unbased_unsized(const AstNode *node) // adds a wire to the current module with the given name that matches the // dimensions of the given wire reference -void add_wire_for_ref(const RTLIL::Wire *ref, const std::string &str) +void add_wire_for_ref(location loc, const RTLIL::Wire *ref, const std::string &str) { - std::unique_ptr left = AstNode::mkconst_int(ref->width - 1 + ref->start_offset, true); - std::unique_ptr right = AstNode::mkconst_int(ref->start_offset, true); + std::unique_ptr left = AstNode::mkconst_int(loc, ref->width - 1 + ref->start_offset, true); + std::unique_ptr right = AstNode::mkconst_int(loc, ref->start_offset, true); if (ref->upto) std::swap(left, right); - std::unique_ptr range = std::make_unique(AST_RANGE, std::move(left), std::move(right)); + std::unique_ptr range = std::make_unique(loc, AST_RANGE, std::move(left), std::move(right)); - std::unique_ptr wire = std::make_unique(AST_WIRE, std::move(range)); + std::unique_ptr wire = std::make_unique(loc, AST_WIRE, std::move(range)); wire->is_signed = ref->is_signed; wire->is_logic = true; wire->str = str; @@ -790,7 +793,7 @@ std::unique_ptr AstNode::clone_at_zero() YS_FALLTHROUGH case AST_MEMRD: detectSignWidth(width_hint, sign_hint); - return mkconst_int(0, sign_hint, width_hint); + return mkconst_int(location, 0, sign_hint, width_hint); default: break; @@ -842,7 +845,7 @@ static void mark_auto_nosync(AstNode *block, const AstNode *wire) { log_assert(block->type == AST_BLOCK); log_assert(wire->type == AST_WIRE); - block->set_attribute(auto_nosync_prefix + wire->str, AstNode::mkconst_int(1, false)); + block->set_attribute(auto_nosync_prefix + wire->str, AstNode::mkconst_int(block->location, 1, false)); } // block names can be prefixed with an explicit scope during elaboration @@ -883,7 +886,7 @@ static void check_auto_nosync(AstNode *node) // mark the wire with `nosync` AstNode *wire = it->second; log_assert(wire->type == AST_WIRE); - wire->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire->set_attribute(ID::nosync, AstNode::mkconst_int(wire->location, 1, false)); } // remove the attributes we've "consumed" @@ -931,7 +934,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin #if 0 log("-------------\n"); - log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, location.filename.c_str(), location.first_line, type2str(type).c_str(), this); + log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, location.begin.filename->c_str(), location.begin.line, type2str(type).c_str(), this); log("const_fold=%d, stage=%d, width_hint=%d, sign_hint=%d\n", int(const_fold), int(stage), int(width_hint), int(sign_hint)); // dumpAst(nullptr, "> "); @@ -1013,16 +1016,17 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (node->children[0]->range_swapped) std::swap(data_range_left, data_range_right); + auto loc = node->location; for (int i = 0; i < mem_size; i++) { - auto reg = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, - mkconst_int(data_range_left, true), mkconst_int(data_range_right, true))); + auto reg = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, + mkconst_int(loc, data_range_left, true), mkconst_int(loc, data_range_right, true))); reg->str = stringf("%s[%d]", node->str.c_str(), i); reg->is_reg = true; reg->is_signed = node->is_signed; for (auto &it : node->attributes) if (it.first != ID::mem2reg) reg->set_attribute(it.first, it.second->clone()); - reg->location.filename = node->location.filename; + reg->location.begin.filename = node->location.begin.filename; reg->location = node->location; while (reg->simplify(true, 1, -1, false)) { } children.push_back(std::move(reg)); @@ -1051,7 +1055,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // 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(location.filename, location.first_line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); delete_children(); str = std::string(); } @@ -1061,7 +1065,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { if (!current_always) { - log_file_warning(location.filename, location.first_line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str()); + log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str()); delete_children(); str = std::string(); } else { @@ -1112,7 +1116,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) { for (auto& c : node->children[0]->children) { if (!c->is_simple_const_expr()) - set_attribute(ID::dynports, AstNode::mkconst_int(1, true)); + set_attribute(ID::dynports, AstNode::mkconst_int(c->location, 1, true)); } } if (this_wire_scope.count(node->str) > 0) { @@ -1338,15 +1342,15 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // create the indirection wire std::stringstream sstr; - sstr << "$indirect$" << ref->name.c_str() << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$indirect$" << ref->name.c_str() << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); std::string tmp_str = sstr.str(); - add_wire_for_ref(ref, tmp_str); + add_wire_for_ref(location, ref, tmp_str); - auto asgn_owned = std::make_unique(AST_ASSIGN); + auto asgn_owned = std::make_unique(child->location, AST_ASSIGN); auto* asgn = asgn_owned.get(); current_ast_mod->children.push_back(std::move(asgn_owned)); - auto ident = std::make_unique(AST_IDENTIFIER); + auto ident = std::make_unique(child->location, AST_IDENTIFIER); ident->str = tmp_str; child->children[0] = ident->clone(); @@ -1509,7 +1513,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (child->children.size() == 0) { // Base type (e.g., int) width = child->range_left - child->range_right +1; - node = mkconst_int(width, child->is_signed); + node = mkconst_int(child->location, width, child->is_signed); } else { // User defined type log_assert(child->children[0]->type == AST_WIRETYPE); @@ -1532,7 +1536,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (template_node->children.size() > 0 && template_node->children[0]->type == AST_RANGE) width = range_width(this, template_node->children[0].get()); child->delete_children(); - node = mkconst_int(width, true); + node = mkconst_int(child->location, width, true); break; } @@ -1540,7 +1544,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin case AST_UNION: { child->delete_children(); width = size_packed_struct(template_node, 0); - node = mkconst_int(width, false); + node = mkconst_int(child->location, width, false); break; } @@ -1872,7 +1876,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin input_error("Defparam argument `%s . %s` does not match a cell!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str()); - auto paraset = std::make_unique(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : nullptr); + auto paraset = std::make_unique(location, AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : nullptr); paraset->str = paramname; AstNode *cell = current_scope.at(modname); @@ -1914,7 +1918,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (!str.empty() && str[0] == '\\' && (template_node->type == AST_STRUCT || template_node->type == AST_UNION)) { // replace instance with wire representing the packed structure newNode = make_packed_struct(template_node.get(), str, attributes); - newNode->set_attribute(ID::wiretype, mkconst_str(resolved_type_node->str)); + newNode->set_attribute(ID::wiretype, mkconst_str(newNode->location, resolved_type_node->str)); // add original input/output attribute to resolved wire newNode->is_input = this->is_input; newNode->is_output = this->is_output; @@ -1925,7 +1929,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // Prepare replacement node. newNode = template_node->clone(); newNode->str = str; - newNode->set_attribute(ID::wiretype, mkconst_str(resolved_type_node->str)); + newNode->set_attribute(ID::wiretype, mkconst_str(newNode->location, resolved_type_node->str)); newNode->is_input = is_input; newNode->is_output = is_output; newNode->is_wand = is_wand; @@ -2016,7 +2020,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (children[1]->type != AST_CONSTANT) input_error("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.to_bits(), children[1]->is_signed); + newNode = mkconst_bits(location, new_value.to_bits(), children[1]->is_signed); goto apply_newNode; } @@ -2078,7 +2082,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin range_swapped = force_upto; } if (range_left == range_right && !attributes.count(ID::single_bit_vector)) - set_attribute(ID::single_bit_vector, mkconst_int(1, false)); + set_attribute(ID::single_bit_vector, mkconst_int(location, 1, false)); } } else { if (!range_valid) @@ -2105,7 +2109,8 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin int left = width - 1, right = 0; if (i) std::swap(left, right); - children[i] = std::make_unique(AST_RANGE, mkconst_int(left, true), mkconst_int(right, true)); + auto loc = children[i]->location; + children[i] = std::make_unique(loc, AST_RANGE, mkconst_int(loc, left, true), mkconst_int(loc, right, true)); fixup_hierarchy_flags(); did_something = true; } else if (children[i]->type == AST_RANGE) { @@ -2176,9 +2181,9 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin 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(location.filename, location.first_line, "converting real value %e to binary %s.\n", + log_file_warning(*location.begin.filename, location.begin.line, "converting real value %e to binary %s.\n", children[0]->realvalue, log_signal(constvalue)); - children[0] = mkconst_bits(constvalue.to_bits(), sign_hint); + children[0] = mkconst_bits(location, constvalue.to_bits(), sign_hint); fixup_hierarchy_flags(); did_something = true; } @@ -2186,7 +2191,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (width != int(children[0]->bits.size())) { RTLIL::SigSpec sig(children[0]->bits); sig.extend_u0(width, children[0]->is_signed); - children[0] = mkconst_bits(sig.as_const().to_bits(), is_signed); + children[0] = mkconst_bits(location, sig.as_const().to_bits(), is_signed); fixup_hierarchy_flags(); } children[0]->is_signed = is_signed; @@ -2198,7 +2203,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } else if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) { double as_realvalue = children[0]->asReal(sign_hint); - children[0] = std::make_unique(AST_REALVALUE); + children[0] = std::make_unique(location, AST_REALVALUE); children[0]->realvalue = as_realvalue; fixup_hierarchy_flags(); did_something = true; @@ -2227,7 +2232,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (found_sname) { // structure member, rewrite this node to reference the packed struct wire auto range = make_index_range(item_node); - newNode = std::make_unique(AST_IDENTIFIER, std::move(range)); + newNode = std::make_unique(location, AST_IDENTIFIER, std::move(range)); newNode->str = sname; // save type and original number of dimensions for $size() etc. newNode->set_attribute(ID::wiretype, item_node->clone()); @@ -2239,7 +2244,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } newNode->basic_prep = true; if (item_node->is_signed) - newNode = std::make_unique(AST_TO_SIGNED, std::move(newNode)); + newNode = std::make_unique(location, AST_TO_SIGNED, std::move(newNode)); goto apply_newNode; } } @@ -2287,7 +2292,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (current_ast_mod == nullptr) { input_error("Identifier `%s' is implicitly declared outside of a module.\n", str.c_str()); } else if (flag_autowire || str == "\\$global_clock") { - auto auto_wire = std::make_unique(AST_AUTOWIRE); + auto auto_wire = std::make_unique(location, AST_AUTOWIRE); auto_wire->str = str; current_scope[str] = auto_wire.get(); current_ast_mod->children.push_back(std::move(auto_wire)); @@ -2318,21 +2323,21 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin std::swap(data_range_left, data_range_right); std::stringstream sstr; - sstr << "$mem2bits$" << str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$mem2bits$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); std::string wire_id = sstr.str(); - auto wire_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true))); + auto wire_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, data_range_left, true), mkconst_int(location, data_range_right, true))); auto* wire = wire_owned.get(); current_ast_mod->children.push_back(std::move(wire_owned)); wire->str = wire_id; if (current_block) - wire->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire->simplify(true, 1, -1, false)) { } auto data = clone(); data->children.pop_back(); - auto assign = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), std::move(data)); + auto assign = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), std::move(data)); assign->children[0]->str = wire_id; assign->children[0]->was_checked = true; @@ -2347,12 +2352,12 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } else { - auto proc = std::make_unique(AST_ALWAYS, std::make_unique(AST_BLOCK)); + auto proc = std::make_unique(location, AST_ALWAYS, std::make_unique(location, AST_BLOCK)); proc->children[0]->children.push_back(std::move(assign)); current_ast_mod->children.push_back(std::move(proc)); } - newNode = std::make_unique(AST_IDENTIFIER, children[1]->clone()); + newNode = std::make_unique(location, AST_IDENTIFIER, children[1]->clone()); newNode->str = wire_id; newNode->integer = integer; // save original number of dimensions for $size() etc. newNode->id2ast = wire; @@ -2442,7 +2447,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } } - varbuf = std::make_unique(AST_LOCALPARAM, std::move(varbuf)); + varbuf = std::make_unique(location, AST_LOCALPARAM, std::move(varbuf)); varbuf->str = init_ast->children[0]->str; AstNode *backup_scope_varbuf = current_scope[varbuf->str]; @@ -2607,7 +2612,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (buf) { if (buf->type != AST_GENBLOCK) - buf = std::make_unique(AST_GENBLOCK, std::move(buf)); + buf = std::make_unique(location, AST_GENBLOCK, std::move(buf)); if (!buf->str.empty()) { buf->expand_genblock(buf->str + "."); @@ -2707,7 +2712,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (!children.at(0)->range_valid) input_error("Non-constant array range on cell array.\n"); - newNode = std::make_unique(AST_GENBLOCK); + newNode = std::make_unique(location, 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; for (int i = 0; i < num; i++) { @@ -2751,15 +2756,15 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin auto& mux_input = children_list.at(1); if (str == "notif0" || str == "notif1") { - mux_input = std::make_unique(AST_BIT_NOT, std::move(mux_input)); + mux_input = std::make_unique(location, AST_BIT_NOT, std::move(mux_input)); } - auto node = std::make_unique(AST_TERNARY, std::move(children_list.at(2))); + auto node = std::make_unique(location, AST_TERNARY, std::move(children_list.at(2))); if (str == "bufif0") { - node->children.push_back(AstNode::mkconst_bits(z_const, false)); + node->children.push_back(AstNode::mkconst_bits(location, z_const, false)); node->children.push_back(std::move(mux_input)); } else { node->children.push_back(std::move(mux_input)); - node->children.push_back(AstNode::mkconst_bits(z_const, false)); + node->children.push_back(AstNode::mkconst_bits(location, z_const, false)); } str.clear(); @@ -2774,11 +2779,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin { auto& input = children_list.back(); if (str == "not") - input = std::make_unique(AST_BIT_NOT, std::move(input)); + input = std::make_unique(location, AST_BIT_NOT, std::move(input)); - newNode = std::make_unique(AST_GENBLOCK); + newNode = std::make_unique(location, AST_GENBLOCK); for (auto it = children_list.begin(); it != std::prev(children_list.end()); it++) { - newNode->children.push_back(std::make_unique(AST_ASSIGN, std::move(*it), input->clone())); + newNode->children.push_back(std::make_unique(location, AST_ASSIGN, std::move(*it), input->clone())); newNode->children.back()->was_checked = true; } @@ -2806,11 +2811,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin auto& node = children_list[1]; if (op_type != AST_POS) for (size_t i = 2; i < children_list.size(); i++) { - node = std::make_unique(op_type, std::move(node), std::move(children_list[i])); + node = std::make_unique(location, op_type, std::move(node), std::move(children_list[i])); node->location = location; } if (invert_results) - node = std::make_unique(AST_BIT_NOT, std::move(node)); + node = std::make_unique(location, AST_BIT_NOT, std::move(node)); str.clear(); type = AST_ASSIGN; @@ -2945,13 +2950,13 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin int rvalue_width; bool rvalue_sign; children[1]->detectSignWidth(rvalue_width, rvalue_sign); - auto rvalue = mktemp_logic("$bitselwrite$rvalue$", current_ast_mod, true, rvalue_width - 1, 0, rvalue_sign); + auto rvalue = mktemp_logic(location, "$bitselwrite$rvalue$", current_ast_mod, true, rvalue_width - 1, 0, rvalue_sign); auto* rvalue_leaky = rvalue.get(); log("make 1\n"); - auto case_node_owned = std::make_unique(AST_CASE, std::move(shift_expr)); + auto case_node_owned = std::make_unique(location, AST_CASE, std::move(shift_expr)); auto* case_node = case_node_owned.get(); - newNode = std::make_unique(AST_BLOCK, - std::make_unique(AST_ASSIGN_EQ, std::move(rvalue), children[1]->clone()), + newNode = std::make_unique(location, AST_BLOCK, + std::make_unique(location, AST_ASSIGN_EQ, std::move(rvalue), children[1]->clone()), std::move(case_node_owned)); did_something = true; @@ -2965,14 +2970,14 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (start_bit%bitno_div != 0 || (stride == 0 && start_bit != 0)) continue; - auto cond = std::make_unique(AST_COND, mkconst_int(start_bit, case_sign_hint, max_width)); + auto cond = std::make_unique(location, AST_COND, mkconst_int(location, start_bit, case_sign_hint, max_width)); auto lvalue = children[0]->clone(); lvalue->delete_children(); if (member_node) lvalue->set_attribute(ID::wiretype, member_node->clone()); - lvalue->children.push_back(std::make_unique(AST_RANGE, - mkconst_int(end_bit, true), mkconst_int(start_bit, true))); - cond->children.push_back(std::make_unique(AST_BLOCK, std::make_unique(std::move(type), std::move(lvalue), rvalue_leaky->clone()))); + lvalue->children.push_back(std::make_unique(location, AST_RANGE, + mkconst_int(location, end_bit, true), mkconst_int(location, start_bit, true))); + cond->children.push_back(std::make_unique(location, AST_BLOCK, std::make_unique(location, std::move(type), std::move(lvalue), rvalue_leaky->clone()))); case_node->children.push_back(std::move(cond)); } } else { @@ -2993,50 +2998,50 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin shift_expr->detectSignWidth(shift_width_hint, shift_sign_hint); // All operations are carried out in a new block. - newNode = std::make_unique(AST_BLOCK); + newNode = std::make_unique(location, AST_BLOCK); // Temporary register holding the result of the bit- or part-select position expression. - auto pos = mktemp_logic("$bitselwrite$pos$", current_ast_mod, true, shift_width_hint - 1, 0, shift_sign_hint); + auto pos = mktemp_logic(location, "$bitselwrite$pos$", current_ast_mod, true, shift_width_hint - 1, 0, shift_sign_hint); // Calculate lsb from position. auto shift_val = pos->clone(); - newNode->children.push_back(std::make_unique(AST_ASSIGN_EQ, std::move(pos), std::move(shift_expr))); + newNode->children.push_back(std::make_unique(location, AST_ASSIGN_EQ, std::move(pos), std::move(shift_expr))); // If the expression is signed, we must add an extra bit for possible negation of the most negative number. // If the expression is unsigned, we must add an extra bit for sign. - shift_val = std::make_unique(AST_CAST_SIZE, mkconst_int(shift_width_hint + 1, true), std::move(shift_val)); + shift_val = std::make_unique(location, AST_CAST_SIZE, mkconst_int(location, shift_width_hint + 1, true), std::move(shift_val)); if (!shift_sign_hint) - shift_val = std::make_unique(AST_TO_SIGNED, std::move(shift_val)); + shift_val = std::make_unique(location, AST_TO_SIGNED, std::move(shift_val)); // offset the shift amount by the lower bound of the dimension if (wire_offset != 0) - shift_val = std::make_unique(AST_SUB, std::move(shift_val), mkconst_int(wire_offset, true)); + shift_val = std::make_unique(location, AST_SUB, std::move(shift_val), mkconst_int(location, wire_offset, true)); // reflect the shift amount if the dimension is swapped if (children[0]->id2ast->range_swapped) - shift_val = std::make_unique(AST_SUB, mkconst_int(wire_width - result_width, true), std::move(shift_val)); + shift_val = std::make_unique(location, AST_SUB, mkconst_int(location, wire_width - result_width, true), std::move(shift_val)); // AST_SHIFT uses negative amounts for shifting left - shift_val = std::make_unique(AST_NEG, std::move(shift_val)); + shift_val = std::make_unique(location, AST_NEG, std::move(shift_val)); auto also_shift_val = shift_val->clone(); // dst = (dst & ~(width'1 << lsb)) | unsigned'(width'(src)) << lsb) did_something = true; - auto bitmask = mkconst_bits(std::vector(result_width, State::S1), false); + auto bitmask = mkconst_bits(location, std::vector(result_width, State::S1), false); newNode->children.push_back( - std::make_unique(std::move(type), + std::make_unique(location, std::move(type), std::move(lvalue), - std::make_unique(AST_BIT_OR, - std::make_unique(AST_BIT_AND, + std::make_unique(location, AST_BIT_OR, + std::make_unique(location, AST_BIT_AND, std::move(old_data), - std::make_unique(AST_BIT_NOT, - std::make_unique(AST_SHIFT, + std::make_unique(location, AST_BIT_NOT, + std::make_unique(location, AST_SHIFT, std::move(bitmask), std::move(shift_val)))), - std::make_unique(AST_SHIFT, - std::make_unique(AST_TO_UNSIGNED, - std::make_unique(AST_CAST_SIZE, - mkconst_int(result_width, true), + std::make_unique(location, AST_SHIFT, + std::make_unique(location, AST_TO_UNSIGNED, + std::make_unique(location, AST_CAST_SIZE, + mkconst_int(location, result_width, true), children[1]->clone())), std::move(also_shift_val))))); @@ -3052,7 +3057,7 @@ skip_dynamic_range_lvalue_expansion:; children.size() == 1 && children[0]->type == AST_RANGE && children[0]->children.size() == 1) { if (integer < (unsigned)id2ast->unpacked_dimensions) input_error("Insufficient number of array indices for %s.\n", log_id(str)); - newNode = std::make_unique(AST_MEMRD, children[0]->children[0]->clone()); + newNode = std::make_unique(location, AST_MEMRD, children[0]->children[0]->clone()); newNode->str = str; newNode->id2ast = id2ast; goto apply_newNode; @@ -3070,22 +3075,22 @@ skip_dynamic_range_lvalue_expansion:; if (found_nontrivial_member) { - newNode = std::make_unique(AST_BLOCK); + newNode = std::make_unique(location, AST_BLOCK); - auto wire_tmp_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true))); + auto wire_tmp_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, width_hint-1, true), mkconst_int(location, 0, true))); auto wire_tmp = wire_tmp_owned.get(); - wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", RTLIL::encode_filename(location.filename).c_str(), location.first_line, autoidx++); + wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line, autoidx++); current_scope[wire_tmp->str] = wire_tmp; current_ast_mod->children.push_back(std::move(wire_tmp_owned)); - wire_tmp->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire_tmp->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire_tmp->simplify(true, 1, -1, false)) { } wire_tmp->is_logic = true; - auto wire_tmp_id_owned = std::make_unique(AST_IDENTIFIER); + auto wire_tmp_id_owned = std::make_unique(location, AST_IDENTIFIER); auto* wire_tmp_id = wire_tmp_id_owned.get(); wire_tmp_id->str = wire_tmp->str; - newNode->children.push_back(std::make_unique(AST_ASSIGN_EQ, std::move(wire_tmp_id_owned), children[1]->clone())); + newNode->children.push_back(std::make_unique(location, AST_ASSIGN_EQ, std::move(wire_tmp_id_owned), children[1]->clone())); newNode->children.back()->was_checked = true; int cursor = 0; @@ -3096,8 +3101,8 @@ skip_dynamic_range_lvalue_expansion:; child->detectSignWidth(child_width_hint, child_sign_hint); auto rhs = wire_tmp_id->clone(); - rhs->children.push_back(std::make_unique(AST_RANGE, AstNode::mkconst_int(cursor+child_width_hint-1, true), AstNode::mkconst_int(cursor, true))); - newNode->children.push_back(std::make_unique(type, child->clone(), std::move(rhs))); + rhs->children.push_back(std::make_unique(location, AST_RANGE, AstNode::mkconst_int(location, cursor+child_width_hint-1, true), AstNode::mkconst_int(location, cursor, true))); + newNode->children.push_back(std::make_unique(location, type, child->clone(), std::move(rhs))); cursor += child_width_hint; } @@ -3116,15 +3121,15 @@ skip_dynamic_range_lvalue_expansion:; input_error("Insufficient number of array indices for %s.\n", log_id(str)); std::stringstream sstr; - sstr << "$memwr$" << children[0]->str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$memwr$" << children[0]->str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.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; bool mem_signed = children[0]->id2ast->is_signed; children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits); - newNode = std::make_unique(AST_BLOCK); - auto defNode = std::make_unique(AST_BLOCK); + newNode = std::make_unique(location, AST_BLOCK); + auto defNode = std::make_unique(location, AST_BLOCK); int data_range_left = children[0]->id2ast->children[0]->range_left; int data_range_right = children[0]->id2ast->children[0]->range_right; @@ -3147,7 +3152,7 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->children[0]->children[0]->isConst()) { node_addr = children[0]->children[0]->children[0]->clone(); } else { - auto wire_addr_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true))); + auto wire_addr_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, addr_bits-1, true), mkconst_int(location, 0, true))); auto* wire_addr = wire_addr_owned.get(); wire_addr->str = id_addr; wire_addr->was_checked = true; @@ -3155,17 +3160,17 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_addr->str] = wire_addr; while (wire_addr->simplify(true, 1, -1, false)) { } - auto assign_addr = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); + auto assign_addr = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), mkconst_bits(location, x_bits_addr, false)); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; defNode->children.push_back(std::move(assign_addr)); - assign_addr = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); + assign_addr = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; newNode->children.push_back(std::move(assign_addr)); - node_addr = std::make_unique(AST_IDENTIFIER); + node_addr = std::make_unique(location, AST_IDENTIFIER); node_addr->str = id_addr; } @@ -3173,7 +3178,7 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->children.size() == 1 && children[1]->isConst()) { node_data = children[1]->clone(); } else { - auto wire_data_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); + auto wire_data_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, mem_width-1, true), mkconst_int(location, 0, true))); auto* wire_data = wire_data_owned.get(); wire_data->str = id_data; wire_data->was_checked = true; @@ -3182,16 +3187,16 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(std::move(wire_data_owned)); while (wire_data->simplify(true, 1, -1, false)) { } - auto assign_data = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); + auto assign_data = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), mkconst_bits(location, x_bits_data, false)); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; defNode->children.push_back(std::move(assign_data)); - node_data = std::make_unique(AST_IDENTIFIER); + node_data = std::make_unique(location, AST_IDENTIFIER); node_data->str = id_data; } - auto wire_en_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); + auto wire_en_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, mem_width-1, true), mkconst_int(location, 0, true))); auto* wire_en = wire_en_owned.get(); wire_en->str = id_en; wire_en->was_checked = true; @@ -3199,12 +3204,12 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(std::move(wire_en_owned)); while (wire_en->simplify(true, 1, -1, false)) { } - auto assign_en_first = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); + auto assign_en_first = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), mkconst_int(location, 0, false, mem_width)); assign_en_first->children[0]->str = id_en; assign_en_first->children[0]->was_checked = true; defNode->children.push_back(std::move(assign_en_first)); - auto node_en = std::make_unique(AST_IDENTIFIER); + auto node_en = std::make_unique(location, AST_IDENTIFIER); node_en->str = id_en; if (!defNode->children.empty()) @@ -3222,14 +3227,14 @@ skip_dynamic_range_lvalue_expansion:; std::vector padding_x(offset, RTLIL::State::Sx); - assign_data = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), - std::make_unique(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone())); + assign_data = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), + std::make_unique(location, AST_CONCAT, mkconst_bits(location, padding_x, false), children[1]->clone())); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; for (int i = 0; i < mem_width; i++) set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), mkconst_bits(location, set_bits_en, false)); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; } @@ -3248,17 +3253,17 @@ skip_dynamic_range_lvalue_expansion:; offset_ast = the_range->children[0]->clone(); if (mem_data_range_offset) - offset_ast = std::make_unique(AST_SUB, std::move(offset_ast), mkconst_int(mem_data_range_offset, true)); + offset_ast = std::make_unique(location, AST_SUB, std::move(offset_ast), mkconst_int(location, mem_data_range_offset, true)); - assign_data = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), - std::make_unique(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); + assign_data = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), + std::make_unique(location, AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; for (int i = 0; i < mem_width; i++) set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), - std::make_unique(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); + assign_en = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), + std::make_unique(location, AST_SHIFT_LEFT, mkconst_bits(location, set_bits_en, false), offset_ast->clone())); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; } @@ -3266,12 +3271,12 @@ skip_dynamic_range_lvalue_expansion:; else { if (!(children[0]->children.size() == 1 && children[1]->isConst())) { - assign_data = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), children[1]->clone()); + assign_data = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), children[1]->clone()); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; } - assign_en = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), mkconst_bits(location, set_bits_en, false)); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; } @@ -3282,21 +3287,21 @@ skip_dynamic_range_lvalue_expansion:; std::unique_ptr wrnode; if (current_always->type == AST_INITIAL) - wrnode = std::make_unique(AST_MEMINIT, std::move(node_addr), std::move(node_data), std::move(node_en), mkconst_int(1, false)); + wrnode = std::make_unique(location, AST_MEMINIT, std::move(node_addr), std::move(node_data), std::move(node_en), mkconst_int(location, 1, false)); else - wrnode = std::make_unique(AST_MEMWR, std::move(node_addr), std::move(node_data), std::move(node_en)); + wrnode = std::make_unique(location, AST_MEMWR, std::move(node_addr), std::move(node_data), std::move(node_en)); wrnode->str = children[0]->str; wrnode->id2ast = children[0]->id2ast; wrnode->location = location; if (wrnode->type == AST_MEMWR) { int portid = current_memwr_count[wrnode->str]++; - wrnode->children.push_back(mkconst_int(portid, false)); + wrnode->children.push_back(mkconst_int(location, portid, false)); std::vector priority_mask; for (int i = 0; i < portid; i++) { bool has_prio = current_memwr_visible[wrnode->str].count(i); priority_mask.push_back(State(has_prio)); } - wrnode->children.push_back(mkconst_bits(priority_mask, false)); + wrnode->children.push_back(mkconst_bits(location, priority_mask, false)); current_memwr_visible[wrnode->str].insert(portid); current_always->children.push_back(std::move(wrnode)); } else { @@ -3304,7 +3309,7 @@ skip_dynamic_range_lvalue_expansion:; } if (newNode->children.empty()) { - newNode = std::make_unique(); + newNode = std::make_unique(location); } goto apply_newNode; } @@ -3318,13 +3323,13 @@ skip_dynamic_range_lvalue_expansion:; { int myidx = autoidx++; - auto wire_owned = std::make_unique(AST_WIRE); + auto wire_owned = std::make_unique(location, AST_WIRE); auto* wire = wire_owned.get(); current_ast_mod->children.push_back(std::move(wire_owned)); wire->str = stringf("$initstate$%d_wire", myidx); while (wire->simplify(true, 1, -1, false)) { } - auto cell = std::make_unique(AST_CELL, std::make_unique(AST_CELLTYPE), std::make_unique(AST_ARGUMENT, std::make_unique(AST_IDENTIFIER))); + auto cell = std::make_unique(location, AST_CELL, std::make_unique(location, AST_CELLTYPE), std::make_unique(location, AST_ARGUMENT, std::make_unique(location, AST_IDENTIFIER))); cell->str = stringf("$initstate$%d", myidx); cell->children[0]->str = "$initstate"; cell->children[1]->str = "\\Y"; @@ -3333,7 +3338,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(std::move(cell)); while (cell->simplify(true, 1, -1, false)) { } - newNode = std::make_unique(AST_IDENTIFIER); + newNode = std::make_unique(location, AST_IDENTIFIER); newNode->str = wire->str; newNode->id2ast = wire; goto apply_newNode; @@ -3382,19 +3387,19 @@ skip_dynamic_range_lvalue_expansion:; for (int i = 0; i < num_steps; i++) { - auto reg_owned = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, - mkconst_int(width_hint-1, true), mkconst_int(0, true))); + auto reg_owned = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, + mkconst_int(location, width_hint-1, true), mkconst_int(location, 0, true))); auto* reg = reg_owned.get(); current_ast_mod->children.push_back(std::move(reg_owned)); - reg->str = stringf("$past$%s:%d$%d$%d", RTLIL::encode_filename(location.filename).c_str(), location.first_line, myidx, i); + reg->str = stringf("$past$%s:%d$%d$%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line, myidx, i); reg->is_reg = true; reg->is_signed = sign_hint; while (reg->simplify(true, 1, -1, false)) { } - auto regid = std::make_unique(AST_IDENTIFIER); + auto regid = std::make_unique(location, AST_IDENTIFIER); regid->str = reg->str; regid->id2ast = reg; regid->was_checked = true; @@ -3404,16 +3409,16 @@ skip_dynamic_range_lvalue_expansion:; if (outreg == nullptr) { rhs = children.at(0)->clone(); } else { - rhs = std::make_unique(AST_IDENTIFIER); + rhs = std::make_unique(location, AST_IDENTIFIER); rhs->str = outreg->str; rhs->id2ast = outreg; } - block->children.push_back(std::make_unique(AST_ASSIGN_LE, std::move(regid), std::move(rhs))); + block->children.push_back(std::make_unique(location, AST_ASSIGN_LE, std::move(regid), std::move(rhs))); outreg = reg; } - newNode = std::make_unique(AST_IDENTIFIER); + newNode = std::make_unique(location, AST_IDENTIFIER); newNode->str = outreg->str; newNode->id2ast = outreg; goto apply_newNode; @@ -3434,20 +3439,20 @@ skip_dynamic_range_lvalue_expansion:; past->str = "\\$past"; if (str == "\\$stable") - newNode = std::make_unique(AST_EQ, std::move(past), std::move(present)); + newNode = std::make_unique(location, AST_EQ, std::move(past), std::move(present)); else if (str == "\\$changed") - newNode = std::make_unique(AST_NE, std::move(past), std::move(present)); + newNode = std::make_unique(location, AST_NE, std::move(past), std::move(present)); else if (str == "\\$rose") - newNode = std::make_unique(AST_LOGIC_AND, - std::make_unique(AST_LOGIC_NOT, std::make_unique(AST_BIT_AND, std::move(past), mkconst_int(1,false))), - std::make_unique(AST_BIT_AND, std::move(present), mkconst_int(1,false))); + newNode = std::make_unique(location, AST_LOGIC_AND, + std::make_unique(location, AST_LOGIC_NOT, std::make_unique(location, AST_BIT_AND, std::move(past), mkconst_int(location, 1, false))), + std::make_unique(location, AST_BIT_AND, std::move(present), mkconst_int(location, 1, false))); else if (str == "\\$fell") - newNode = std::make_unique(AST_LOGIC_AND, - std::make_unique(AST_BIT_AND, std::move(past), mkconst_int(1,false)), - std::make_unique(AST_LOGIC_NOT, std::make_unique(AST_BIT_AND, std::move(present), mkconst_int(1,false)))); + newNode = std::make_unique(location, AST_LOGIC_AND, + std::make_unique(location, AST_BIT_AND, std::move(past), mkconst_int(location, 1, false)), + std::make_unique(location, AST_LOGIC_NOT, std::make_unique(location, AST_BIT_AND, std::move(present), mkconst_int(location, 1, false)))); else log_abort(); @@ -3481,7 +3486,7 @@ skip_dynamic_range_lvalue_expansion:; if (arg_value.at(i) == RTLIL::State::S1) result = i + 1; - newNode = mkconst_int(result, true); + newNode = mkconst_int(location, result, true); goto apply_newNode; } @@ -3572,7 +3577,7 @@ skip_dynamic_range_lvalue_expansion:; else { // str == "\\$bits" result = width * mem_depth; } - newNode = mkconst_int(result, true); + newNode = mkconst_int(location, result, true); goto apply_newNode; } @@ -3618,9 +3623,9 @@ skip_dynamic_range_lvalue_expansion:; } if (str == "\\$rtoi") { - newNode = AstNode::mkconst_int(x, true); + newNode = AstNode::mkconst_int(location, x, true); } else { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); if (str == "\\$ln") newNode->realvalue = ::log(x); else if (str == "\\$log10") newNode->realvalue = ::log10(x); else if (str == "\\$exp") newNode->realvalue = ::exp(x); @@ -3650,7 +3655,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$sformatf") { Fmt fmt = processFormat(stage, /*sformat_like=*/true); - newNode = AstNode::mkconst_str(fmt.render()); + newNode = AstNode::mkconst_str(location, fmt.render()); goto apply_newNode; } @@ -3678,24 +3683,24 @@ skip_dynamic_range_lvalue_expansion:; auto& exp = children[0]; exp->detectSignWidth(exp_width, exp_sign, nullptr); - newNode = mkconst_int(0, false); + newNode = mkconst_int(location, 0, false); for (int i = 0; i < exp_width; i++) { // Generate nodes for: exp << i >> ($size(exp) - 1) // ^^ ^^ - auto lsh_node = std::make_unique(AST_SHIFT_LEFT, exp->clone(), mkconst_int(i, false)); - auto rsh_node = std::make_unique(AST_SHIFT_RIGHT, std::move(lsh_node), mkconst_int(exp_width - 1, false)); + auto lsh_node = std::make_unique(location, AST_SHIFT_LEFT, exp->clone(), mkconst_int(location, i, false)); + auto rsh_node = std::make_unique(location, AST_SHIFT_RIGHT, std::move(lsh_node), mkconst_int(location, exp_width - 1, false)); std::unique_ptr or_node = nullptr; for (RTLIL::State control_bit : control_bits) { // Generate node for: (exp << i >> ($size(exp) - 1)) === control_bit // ^^^ - auto eq_node = std::make_unique(AST_EQX, rsh_node->clone(), mkconst_bits({control_bit}, false)); + auto eq_node = std::make_unique(location, AST_EQX, rsh_node->clone(), mkconst_bits(location, {control_bit}, false)); // Or the result for each checked bit value if (or_node) - or_node = std::make_unique(AST_LOGIC_OR, std::move(or_node), std::move(eq_node)); + or_node = std::make_unique(location, AST_LOGIC_OR, std::move(or_node), std::move(eq_node)); else or_node = std::move(eq_node); } @@ -3705,7 +3710,7 @@ skip_dynamic_range_lvalue_expansion:; log_assert(or_node != nullptr); // Generate node for adding with result of previous bit - newNode = std::make_unique(AST_ADD, std::move(newNode), std::move(or_node)); + newNode = std::make_unique(location, AST_ADD, std::move(newNode), std::move(or_node)); } goto apply_newNode; @@ -3720,18 +3725,18 @@ skip_dynamic_range_lvalue_expansion:; countbits->str = "\\$countbits"; if (str == "\\$countones") { - countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); + countbits->children.push_back(mkconst_bits(location, {RTLIL::State::S1}, false)); newNode = std::move(countbits); } else if (str == "\\$isunknown") { - countbits->children.push_back(mkconst_bits({RTLIL::Sx}, false)); - countbits->children.push_back(mkconst_bits({RTLIL::Sz}, false)); - newNode = std::make_unique(AST_GT, std::move(countbits), mkconst_int(0, false)); + countbits->children.push_back(mkconst_bits(location, {RTLIL::Sx}, false)); + countbits->children.push_back(mkconst_bits(location, {RTLIL::Sz}, false)); + newNode = std::make_unique(location, AST_GT, std::move(countbits), mkconst_int(location, 0, false)); } else if (str == "\\$onehot") { - countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); - newNode = std::make_unique(AST_EQ, std::move(countbits), mkconst_int(1, false)); + countbits->children.push_back(mkconst_bits(location, {RTLIL::State::S1}, false)); + newNode = std::make_unique(location, AST_EQ, std::move(countbits), mkconst_int(location, 1, false)); } else if (str == "\\$onehot0") { - countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); - newNode = std::make_unique(AST_LE, std::move(countbits), mkconst_int(1, false)); + countbits->children.push_back(mkconst_bits(location, {RTLIL::State::S1}, false)); + newNode = std::make_unique(location, AST_LE, std::move(countbits), mkconst_int(location, 1, false)); } else { log_abort(); } @@ -3847,7 +3852,7 @@ skip_dynamic_range_lvalue_expansion:; std::stringstream sstr; - sstr << str << "$func$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++) << '.'; + sstr << str << "$func$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++) << '.'; std::string prefix = sstr.str(); auto* decl = current_scope[str]; @@ -3910,11 +3915,11 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(std::move(wire)); while (wire_leaky->simplify(true, 1, -1, false)) { } - auto lvalue = std::make_unique(AST_IDENTIFIER); + auto lvalue = std::make_unique(location, AST_IDENTIFIER); lvalue->str = wire_leaky->str; - auto always = std::make_unique(AST_ALWAYS, std::make_unique(AST_BLOCK, - std::make_unique(AST_ASSIGN_EQ, std::move(lvalue), clone()))); + auto always = std::make_unique(location, AST_ALWAYS, std::make_unique(location, AST_BLOCK, + std::make_unique(location, AST_ASSIGN_EQ, std::move(lvalue), clone()))); always->children[0]->children[0]->was_checked = true; current_ast_mod->children.push_back(std::move(always)); @@ -3934,14 +3939,14 @@ skip_dynamic_range_lvalue_expansion:; } else celltype = RTLIL::escape_id(celltype); - auto cell = std::make_unique(AST_CELL, std::make_unique(AST_CELLTYPE)); + auto cell = std::make_unique(location, AST_CELL, std::make_unique(location, AST_CELLTYPE)); cell->str = prefix.substr(0, GetSize(prefix)-1); cell->children[0]->str = celltype; for (auto& attr : decl->attributes) if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) { - auto cell_arg = std::make_unique(AST_PARASET, attr.second->clone()); + auto cell_arg = std::make_unique(location, AST_PARASET, attr.second->clone()); cell_arg->str = RTLIL::escape_id(attr.first.substr(strlen("\\via_celltype_defparam_"))); cell->children.push_back(std::move(cell_arg)); } @@ -3956,15 +3961,15 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(std::move(wire)); while (wire->simplify(true, 1, -1, false)) { } - auto wire_id = std::make_unique(AST_IDENTIFIER); + auto wire_id = std::make_unique(location, AST_IDENTIFIER); wire_id->str = wire->str; if ((child->is_input || child->is_output) && arg_count < children.size()) { auto arg = children[arg_count++]->clone(); auto assign = child->is_input ? - std::make_unique(AST_ASSIGN_EQ, wire_id->clone(), std::move(arg)) : - std::make_unique(AST_ASSIGN_EQ, std::move(arg), wire_id->clone()); + std::make_unique(location, AST_ASSIGN_EQ, wire_id->clone(), std::move(arg)) : + std::make_unique(location, AST_ASSIGN_EQ, std::move(arg), wire_id->clone()); assign->children[0]->was_checked = true; for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { @@ -3975,7 +3980,7 @@ skip_dynamic_range_lvalue_expansion:; } } - auto cell_arg = std::make_unique(AST_ARGUMENT, std::move(wire_id)); + auto cell_arg = std::make_unique(location, AST_ARGUMENT, std::move(wire_id)); cell_arg->str = child->str == str ? outport : child->str; cell->children.push_back(std::move(cell_arg)); } @@ -4016,7 +4021,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_input = false; wire->is_output = false; wire->is_reg = true; - wire->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); if (child->type == AST_ENUM_ITEM) wire->set_attribute(ID::enum_base_type, std::move(child->attributes[ID::enum_base_type])); @@ -4047,10 +4052,10 @@ skip_dynamic_range_lvalue_expansion:; break; } if (!uses_explicit_size) { - auto range = std::make_unique(); + auto range = std::make_unique(location); range->type = AST_RANGE; - range->children.push_back(mkconst_int(0, true)); - range->children.push_back(mkconst_int(0, true)); + range->children.push_back(mkconst_int(location, 0, true)); + range->children.push_back(mkconst_int(location, 0, true)); wire->children.push_back(std::move(range)); } } @@ -4060,16 +4065,16 @@ skip_dynamic_range_lvalue_expansion:; continue; } - auto wire_id = std::make_unique(AST_IDENTIFIER); + auto wire_id = std::make_unique(location, AST_IDENTIFIER); wire_id->str = wire->str; if (child->is_input) { - auto assign = std::make_unique(AST_ASSIGN_EQ, wire_id->clone(), arg->clone()); + auto assign = std::make_unique(location, AST_ASSIGN_EQ, wire_id->clone(), arg->clone()); assign->children[0]->was_checked = true; new_stmts.push_back(std::move(assign)); } if (child->is_output) { - auto assign = std::make_unique(AST_ASSIGN_EQ, arg->clone(), wire_id->clone()); + auto assign = std::make_unique(location, AST_ASSIGN_EQ, arg->clone(), wire_id->clone()); assign->children[0]->was_checked = true; output_assignments.push_back(std::move(assign)); } @@ -4140,7 +4145,7 @@ replace_fcall_later:; else data.push_back(RTLIL::State::Sx); } - newNode = mkconst_bits(data, false); + newNode = mkconst_bits(location, data, false); } else if (children.size() == 0) newNode = current_scope[str]->children[0]->clone(); @@ -4152,14 +4157,14 @@ replace_fcall_later:; case AST_BIT_NOT: if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = RTLIL::const_not(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint); - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } break; case AST_TO_SIGNED: case AST_TO_UNSIGNED: if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint); - newNode = mkconst_bits(y.to_bits(), type == AST_TO_SIGNED); + newNode = mkconst_bits(location, y.to_bits(), type == AST_TO_SIGNED); } break; if (0) { case AST_BIT_AND: const_func = RTLIL::const_and; } @@ -4169,7 +4174,7 @@ replace_fcall_later:; if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } break; if (0) { case AST_REDUCE_AND: const_func = RTLIL::const_reduce_and; } @@ -4179,16 +4184,16 @@ replace_fcall_later:; if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; } if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, false, false, -1); - newNode = mkconst_bits(y.to_bits(), false); + newNode = mkconst_bits(location, y.to_bits(), false); } break; case AST_LOGIC_NOT: if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1); - newNode = mkconst_bits(y.to_bits(), false); + newNode = mkconst_bits(location, y.to_bits(), false); } else if (children[0]->isConst()) { - newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1); + newNode = mkconst_int(location, children[0]->asReal(sign_hint) == 0, false, 1); } break; if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; } @@ -4196,13 +4201,13 @@ replace_fcall_later:; if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits), children[0]->is_signed, children[1]->is_signed, -1); - newNode = mkconst_bits(y.to_bits(), false); + newNode = mkconst_bits(location, y.to_bits(), false); } else if (children[0]->isConst() && children[1]->isConst()) { if (type == AST_LOGIC_AND) - newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1); + newNode = mkconst_int(location, (children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1); else - newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1); + newNode = mkconst_int(location, (children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1); } break; if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; } @@ -4213,10 +4218,10 @@ replace_fcall_later:; if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint); - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } else if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); } break; @@ -4233,19 +4238,19 @@ replace_fcall_later:; bool cmp_signed = children[0]->is_signed && children[1]->is_signed; RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed), children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1); - newNode = mkconst_bits(y.to_bits(), false); + newNode = mkconst_bits(location, y.to_bits(), false); } else if (children[0]->isConst() && children[1]->isConst()) { bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed); switch (type) { - case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break; - case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break; - case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; - case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; - case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; - case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; - case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break; - case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break; + case AST_LT: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break; + case AST_LE: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQ: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NE: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQX: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NEX: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_GE: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break; + case AST_GT: newNode = mkconst_int(location, children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break; default: log_abort(); } } @@ -4258,10 +4263,10 @@ replace_fcall_later:; if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } else if (children[0]->isConst() && children[1]->isConst()) { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); switch (type) { case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; @@ -4277,10 +4282,10 @@ replace_fcall_later:; if (0) { case AST_NEG: const_func = RTLIL::const_neg; } if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint); - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } else if (children[0]->isConst()) { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); if (type == AST_NEG) newNode->realvalue = -children[0]->asReal(sign_hint); else @@ -4300,15 +4305,15 @@ replace_fcall_later:; bool other_sign_hint = sign_hint, other_real = false; not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real); if (other_real) { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); choice->detectSignWidth(width_hint, sign_hint); newNode->realvalue = choice->asReal(sign_hint); } else { RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); if (choice->is_string && y.size() % 8 == 0 && sign_hint == false) - newNode = mkconst_str(y.to_bits()); + newNode = mkconst_str(location, y.to_bits()); else - newNode = mkconst_bits(y.to_bits(), sign_hint); + newNode = mkconst_bits(location, y.to_bits(), sign_hint); } } else if (choice->isConst()) { @@ -4321,9 +4326,9 @@ replace_fcall_later:; for (auto i = 0; i < a.size(); i++) if (a[i] != b[i]) a.bits()[i] = RTLIL::State::Sx; - newNode = mkconst_bits(a.to_bits(), sign_hint); + newNode = mkconst_bits(location, a.to_bits(), sign_hint); } else if (children[1]->isConst() && children[2]->isConst()) { - newNode = std::make_unique(AST_REALVALUE); + newNode = std::make_unique(location, AST_REALVALUE); if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint)) newNode->realvalue = children[1]->asReal(sign_hint); else @@ -4342,7 +4347,7 @@ replace_fcall_later:; val = children[1]->bitsAsUnsizedConst(width); else val = children[1]->bitsAsConst(width); - newNode = mkconst_bits(val.to_bits(), children[1]->is_signed); + newNode = mkconst_bits(location, val.to_bits(), children[1]->is_signed); } break; case AST_CONCAT: @@ -4354,14 +4359,14 @@ replace_fcall_later:; string_op = false; tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end()); } - newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false); + newNode = string_op ? mkconst_str(location, tmp_bits) : mkconst_bits(location, tmp_bits, false); break; case AST_REPLICATE: if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT) goto not_const; for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++) tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end()); - newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false); + newNode = children.at(1)->is_string ? mkconst_str(location, tmp_bits) : mkconst_bits(location, tmp_bits, false); break; default: not_const: @@ -4377,7 +4382,7 @@ apply_newNode: // newNode->dumpAst(stderr, "+ "); log_assert(newNode != nullptr); // newNode->null_check(); - newNode->location.filename = location.filename; + newNode->location.begin.filename = location.begin.filename; newNode->location = location; newNode->cloneInto(*this); fixup_hierarchy_flags(); @@ -4405,7 +4410,7 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file int mem_width, mem_size, addr_bits; memory->meminfo(mem_width, mem_size, addr_bits); - auto block = std::make_unique(AST_BLOCK); + auto block = std::make_unique(location, AST_BLOCK); AstNode* meminit = nullptr; int next_meminit_cursor=0; @@ -4424,7 +4429,7 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file #else char slash = '/'; #endif - std::string path = location.filename.substr(0, location.filename.find_last_of(slash)+1); + std::string path = location.begin.filename->substr(0, location.begin.filename->find_last_of(slash)+1); f.open(path + mem_filename.c_str()); yosys_input_files.insert(path + mem_filename); } else { @@ -4489,15 +4494,15 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file if (meminit == nullptr || cursor != next_meminit_cursor) { if (meminit != nullptr) { - meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false); - meminit->children[3] = AstNode::mkconst_int(meminit_size, false); + meminit->children[1] = AstNode::mkconst_bits(location, meminit_bits, false); + meminit->children[3] = AstNode::mkconst_int(location, meminit_size, false); } - auto meminit_owned = std::make_unique(AST_MEMINIT); + auto meminit_owned = std::make_unique(location, AST_MEMINIT); meminit = meminit_owned.get(); - meminit->children.push_back(AstNode::mkconst_int(cursor, false)); + meminit->children.push_back(AstNode::mkconst_int(location, cursor, false)); meminit->children.push_back(nullptr); - meminit->children.push_back(AstNode::mkconst_bits(en_bits, false)); + meminit->children.push_back(AstNode::mkconst_bits(location, en_bits, false)); meminit->children.push_back(nullptr); meminit->str = memory->str; meminit->id2ast = memory; @@ -4514,7 +4519,13 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file } else { - block->children.push_back(std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER, std::make_unique(AST_RANGE, AstNode::mkconst_int(cursor, false))), std::move(value))); + block->children.push_back( + std::make_unique(location, + AST_ASSIGN_EQ, std::make_unique(location, + AST_IDENTIFIER, std::make_unique(location, + AST_RANGE, AstNode::mkconst_int(location, + cursor, false))), + std::move(value))); block->children.back()->children[0]->str = memory->str; block->children.back()->children[0]->id2ast = memory; block->children.back()->children[0]->was_checked = true; @@ -4530,8 +4541,8 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file } if (meminit != nullptr) { - meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false); - meminit->children[3] = AstNode::mkconst_int(meminit_size, false); + meminit->children[1] = AstNode::mkconst_bits(location, meminit_bits, false); + meminit->children[3] = AstNode::mkconst_int(location, meminit_size, false); } return block; @@ -4703,7 +4714,7 @@ static void mark_memories_assign_lhs_complex(dict> & 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", RTLIL::encode_filename(that->location.filename).c_str(), that->location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*that->location.begin.filename).c_str(), that->location.begin.line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS; } } @@ -4731,14 +4742,14 @@ void AstNode::mem2reg_as_needed_pass1(dict> &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", RTLIL::encode_filename(location.filename).c_str(), location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.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", RTLIL::encode_filename(location.filename).c_str(), location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line)); proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1; } @@ -4755,11 +4766,11 @@ void AstNode::mem2reg_as_needed_pass1(dict> &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", RTLIL::encode_filename(location.filename).c_str(), location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.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", RTLIL::encode_filename(location.filename).c_str(), location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE; } } @@ -4776,7 +4787,7 @@ void AstNode::mem2reg_as_needed_pass1(dict> &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", RTLIL::encode_filename(location.filename).c_str(), location.first_line)); + mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(*location.begin.filename).c_str(), location.begin.line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2; } } @@ -4893,7 +4904,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, if (length != 0) { - auto block_owned = std::make_unique(AST_INITIAL, std::make_unique(AST_BLOCK)); + auto block_owned = std::make_unique(location, + AST_INITIAL, std::make_unique(location, + AST_BLOCK)); auto block = block_owned.get(); mod->children.push_back(std::move(block_owned)); block = block->children[0].get(); @@ -4910,7 +4923,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, while (epos < wordsz && en[epos] == State::S1) epos++; int clen = epos - pos; - auto range = std::make_unique(AST_RANGE, AstNode::mkconst_int(cursor+i, false)); + auto range = std::make_unique(location, + AST_RANGE, AstNode::mkconst_int(location, + cursor+i, false)); if (pos != 0 || epos != wordsz) { int left; int right; @@ -4922,20 +4937,29 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, right = mrange->range_right + pos; left = mrange->range_right + epos - 1; } - range = std::make_unique(AST_MULTIRANGE, std::move(range), std::make_unique(AST_RANGE, AstNode::mkconst_int(left, true), AstNode::mkconst_int(right, true))); + range = std::make_unique(location, + AST_MULTIRANGE, std::move(range), std::make_unique(location, + AST_RANGE, + AstNode::mkconst_int(location, left, true), + AstNode::mkconst_int(location, right, true))); } - auto target = std::make_unique(AST_IDENTIFIER, std::move(range)); + auto target = std::make_unique(location, AST_IDENTIFIER, std::move(range)); target->str = str; target->id2ast = id2ast; target->was_checked = true; - block->children.push_back(std::make_unique(AST_ASSIGN_EQ, std::move(target), mkconst_bits(data.extract(i*wordsz + pos, clen).to_bits(), false))); + block->children.push_back(std::make_unique(location, + AST_ASSIGN_EQ, + std::move(target), + mkconst_bits(location, + data.extract(i*wordsz + pos, clen).to_bits(), + false))); pos = epos; } } } } - auto newNode = std::make_unique(AST_NONE); + auto newNode = std::make_unique(location, AST_NONE); newNode->cloneInto(*this); did_something = true; } @@ -4943,7 +4967,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, if (type == AST_ASSIGN && block == nullptr && children[0]->mem2reg_check(mem2reg_set)) { if (async_block == nullptr) { - auto async_block_owned = std::make_unique(AST_ALWAYS, std::make_unique(AST_BLOCK)); + auto async_block_owned = std::make_unique(location, AST_ALWAYS, std::make_unique(location, AST_BLOCK)); async_block = async_block_owned.get(); mod->children.push_back(std::move(async_block_owned)); } @@ -4953,7 +4977,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, newNode->children[0]->was_checked = true; async_block->children[0]->children.push_back(std::move(newNode)); - newNode = std::make_unique(AST_NONE); + newNode = std::make_unique(location, AST_NONE); newNode->cloneInto(*this); did_something = true; } @@ -4962,27 +4986,27 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, children[0]->children[0]->children[0]->type != AST_CONSTANT) { std::stringstream sstr; - sstr << "$mem2reg_wr$" << children[0]->str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$mem2reg_wr$" << children[0]->str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; bool mem_signed = children[0]->id2ast->is_signed; children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits); - auto wire_addr = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true))); + auto wire_addr = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, addr_bits-1, true), mkconst_int(location, 0, true))); wire_addr->str = id_addr; wire_addr->is_reg = true; wire_addr->was_checked = true; - wire_addr->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire_addr->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire_addr->simplify(true, 1, -1, false)) { } mod->children.push_back(std::move(wire_addr)); - auto wire_data = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); + auto wire_data = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, mem_width-1, true), mkconst_int(location, 0, true))); wire_data->str = id_data; wire_data->is_reg = true; wire_data->was_checked = true; wire_data->is_signed = mem_signed; - wire_data->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire_data->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire_data->simplify(true, 1, -1, false)) { } mod->children.push_back(std::move(wire_data)); @@ -4992,18 +5016,18 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, assign_idx++; log_assert(assign_idx < block->children.size()); - auto assign_addr = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); + auto assign_addr = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; block->children.insert(block->children.begin()+assign_idx+1, std::move(assign_addr)); - auto case_node = std::make_unique(AST_CASE, std::make_unique(AST_IDENTIFIER)); + auto case_node = std::make_unique(location, AST_CASE, std::make_unique(location, AST_IDENTIFIER)); case_node->children[0]->str = id_addr; for (int i = 0; i < mem_size; i++) { if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i) continue; - auto cond_node = std::make_unique(AST_COND, AstNode::mkconst_int(i, false, addr_bits), std::make_unique(AST_BLOCK)); - auto assign_reg = std::make_unique(type, std::make_unique(AST_IDENTIFIER), std::make_unique(AST_IDENTIFIER)); + auto cond_node = std::make_unique(location, AST_COND, AstNode::mkconst_int(location, i, false, addr_bits), std::make_unique(location, AST_BLOCK)); + auto assign_reg = std::make_unique(location, type, std::make_unique(location, AST_IDENTIFIER), std::make_unique(location, AST_IDENTIFIER)); if (children[0]->children.size() == 2) assign_reg->children[0]->children.push_back(children[0]->children[1]->clone()); assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i); @@ -5074,51 +5098,51 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, std::vector x_bits; for (int i = 0; i < width; i++) x_bits.push_back(RTLIL::State::Sx); - std::unique_ptr constant = AstNode::mkconst_bits(x_bits, false); + std::unique_ptr constant = AstNode::mkconst_bits(location, x_bits, false); constant->cloneInto(*this); } } else { std::stringstream sstr; - sstr << "$mem2reg_rd$" << str << "$" << RTLIL::encode_filename(location.filename) << ":" << location.first_line << "$" << (autoidx++); + sstr << "$mem2reg_rd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; bool mem_signed = id2ast->is_signed; id2ast->meminfo(mem_width, mem_size, addr_bits); - auto wire_addr = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true))); + auto wire_addr = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, addr_bits-1, true), mkconst_int(location, 0, true))); wire_addr->str = id_addr; wire_addr->is_reg = true; wire_addr->was_checked = true; if (block) - wire_addr->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire_addr->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire_addr->simplify(true, 1, -1, false)) { } mod->children.push_back(std::move(wire_addr)); - auto wire_data = std::make_unique(AST_WIRE, std::make_unique(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); + auto wire_data = std::make_unique(location, AST_WIRE, std::make_unique(location, AST_RANGE, mkconst_int(location, mem_width-1, true), mkconst_int(location, 0, true))); wire_data->str = id_data; wire_data->is_reg = true; wire_data->was_checked = true; wire_data->is_signed = mem_signed; if (block) - wire_data->set_attribute(ID::nosync, AstNode::mkconst_int(1, false)); + wire_data->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); while (wire_data->simplify(true, 1, -1, false)) { } mod->children.push_back(std::move(wire_data)); - auto assign_addr = std::make_unique(block ? AST_ASSIGN_EQ : AST_ASSIGN, std::make_unique(AST_IDENTIFIER), children[0]->children[0]->clone()); + auto assign_addr = std::make_unique(location, block ? AST_ASSIGN_EQ : AST_ASSIGN, std::make_unique(location, AST_IDENTIFIER), children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; - auto case_node = std::make_unique(AST_CASE, std::make_unique(AST_IDENTIFIER)); + auto case_node = std::make_unique(location, AST_CASE, std::make_unique(location, AST_IDENTIFIER)); case_node->children[0]->str = id_addr; for (int i = 0; i < mem_size; i++) { if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i) continue; - auto cond_node = std::make_unique(AST_COND, AstNode::mkconst_int(i, false, addr_bits), std::make_unique(AST_BLOCK)); - auto assign_reg = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), std::make_unique(AST_IDENTIFIER)); + auto cond_node = std::make_unique(location, AST_COND, AstNode::mkconst_int(location, i, false, addr_bits), std::make_unique(location, AST_BLOCK)); + auto assign_reg = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), std::make_unique(location, AST_IDENTIFIER)); assign_reg->children[0]->str = id_data; assign_reg->children[0]->was_checked = true; assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i); @@ -5130,8 +5154,8 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, for (int i = 0; i < mem_width; i++) x_bits.push_back(RTLIL::State::Sx); - auto cond_node = std::make_unique(AST_COND, std::make_unique(AST_DEFAULT), std::make_unique(AST_BLOCK)); - auto assign_reg = std::make_unique(AST_ASSIGN_EQ, std::make_unique(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false)); + auto cond_node = std::make_unique(location, AST_COND, std::make_unique(location, AST_DEFAULT), std::make_unique(location, AST_BLOCK)); + auto assign_reg = std::make_unique(location, AST_ASSIGN_EQ, std::make_unique(location, AST_IDENTIFIER), AstNode::mkconst_bits(location, x_bits, false)); assign_reg->children[0]->str = id_data; assign_reg->children[0]->was_checked = true; cond_node->children[1]->children.push_back(std::move(assign_reg)); @@ -5151,7 +5175,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, } else { - auto proc = std::make_unique(AST_ALWAYS, std::make_unique(AST_BLOCK, std::move(case_node))); + auto proc = std::make_unique(location, AST_ALWAYS, std::make_unique(location, AST_BLOCK, std::move(case_node))); mod->children.push_back(std::move(proc)); mod->children.push_back(std::move(assign_addr)); mod->fixup_hierarchy_flags(); @@ -5306,7 +5330,7 @@ bool AstNode::replace_variables(std::map &varia offset = -offset; std::vector &var_bits = variables.at(str).val.bits(); std::vector new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width); - auto newNode = mkconst_bits(new_bits, variables.at(str).is_signed); + auto newNode = mkconst_bits(location, new_bits, variables.at(str).is_signed); newNode->cloneInto(*this); return true; } @@ -5322,7 +5346,7 @@ std::unique_ptr AstNode::eval_const_function(AstNode *fcall, bool must_ { std::map backup_scope = current_scope; std::map variables; - auto block = std::make_unique(AST_BLOCK); + auto block = std::make_unique(location, AST_BLOCK); std::unique_ptr result = nullptr; size_t argidx = 0; @@ -5547,7 +5571,7 @@ std::unique_ptr AstNode::eval_const_function(AstNode *fcall, bool must_ if (!cond->replace_variables(variables, fcall, must_succeed)) goto finished; - cond = std::make_unique(AST_EQ, expr->clone(), std::move(cond)); + cond = std::make_unique(location, AST_EQ, expr->clone(), std::move(cond)); cond->set_in_param_flag(true); while (cond->simplify(true, 1, -1, false)) { } @@ -5599,7 +5623,7 @@ std::unique_ptr AstNode::eval_const_function(AstNode *fcall, bool must_ log_abort(); } - result = AstNode::mkconst_bits(variables.at(str).val.to_bits(), variables.at(str).is_signed); + result = AstNode::mkconst_bits(location, variables.at(str).val.to_bits(), variables.at(str).is_signed); finished: current_scope = backup_scope; @@ -5615,12 +5639,12 @@ void AstNode::allocateDefaultEnumValues() int last_enum_int = -1; for (auto& node : children) { log_assert(node->type==AST_ENUM_ITEM); - node->set_attribute(ID::enum_base_type, mkconst_str(str)); + node->set_attribute(ID::enum_base_type, mkconst_str(node->location, str)); for (size_t i = 0; i < node->children.size(); i++) { switch (node->children[i]->type) { case AST_NONE: // replace with auto-incremented constant - node->children[i] = AstNode::mkconst_int(++last_enum_int, true); + node->children[i] = AstNode::mkconst_int(node->location, ++last_enum_int, true); break; case AST_CONSTANT: // explicit constant (or folded expression) diff --git a/frontends/verilog/.gitignore b/frontends/verilog/.gitignore index a6d4c8b86..cb6775cbc 100644 --- a/frontends/verilog/.gitignore +++ b/frontends/verilog/.gitignore @@ -2,6 +2,4 @@ verilog_lexer.cc verilog_parser.output verilog_parser.tab.cc verilog_parser.tab.hh -position.hh -location.hh stack.hh diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index 338b13e4b..a563c899c 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -3,11 +3,9 @@ GENFILES += frontends/verilog/verilog_parser.tab.cc GENFILES += frontends/verilog/verilog_parser.tab.hh GENFILES += frontends/verilog/verilog_parser.output GENFILES += frontends/verilog/verilog_lexer.cc -GENFILES += frontends/verilog/location.hh -GENFILES += frontends/verilog/position.hh GENFILES += frontends/verilog/stack.hh -frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y +frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y frontends/verilog/verilog_location.h $(Q) mkdir -p $(dir $@) $(P) $(BISON) -Wall -Werror -o $@ -d -r all -b frontends/verilog/verilog_parser $< diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index cd8f05b9b..5d906cb0f 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -47,7 +47,7 @@ using namespace VERILOG_FRONTEND; std::string ConstParser::fmt_maybe_loc(std::string msg) { std::string s; - s += stringf("%s:%d:", loc.filename, loc.first_line); + s += stringf("%s:%d:", loc.begin.filename->c_str(), loc.begin.line); s += msg; return s; diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d05f87aff..733ec8ba7 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -33,6 +33,7 @@ #include "verilog_frontend.h" #include "verilog_lexer.h" #include "verilog_error.h" +#include "verilog_location.h" #include "preproc.h" #include "kernel/yosys.h" #include "libs/sha1/sha1.h" @@ -277,8 +278,8 @@ struct VerilogFrontend : public Frontend { std::list include_dirs; std::list attributes; - ParseMode parse_mode; - ParseState parse_state; + ParseMode parse_mode = {}; + ParseState parse_state = {}; parse_mode.sv = false; parse_mode.formal = false; parse_mode.noassert = false; @@ -479,11 +480,6 @@ struct VerilogFrontend : public Frontend { break; } - VerilogLexer lexer(&parse_state, &parse_mode, &filename); - frontend_verilog_yy::parser parser(&lexer, &parse_state, &parse_mode); - lexer.set_debug(flag_debug_lexer); - parser.set_debug_level(flag_debug_parser ? 1 : 0); - if (parse_mode.formal || !flag_nosynthesis) defines_map.add(parse_mode.formal ? "FORMAL" : "SYNTHESIS", "1"); @@ -495,13 +491,9 @@ struct VerilogFrontend : public Frontend { parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str()); AST::sv_mode_but_global_and_used_for_literally_one_condition = parse_mode.sv; - - AstSrcLocType top_loc = AstSrcLocType ( "read_verilog", 0, 0, 0, 0); - parse_state.current_ast = new AST::AstNode(top_loc, AST::AST_DESIGN); - - parse_state.lexin = f; std::string code_after_preproc; + parse_state.lexin = f; if (!flag_nopp) { code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, *design->verilog_defines, include_dirs, parse_state, parse_mode); if (flag_ppdump) @@ -509,6 +501,15 @@ struct VerilogFrontend : public Frontend { parse_state.lexin = new std::istringstream(code_after_preproc); } + auto filename_shared = std::make_shared(filename); + auto top_loc = location(); + top_loc.begin.filename = filename_shared; + parse_state.current_ast = new AST::AstNode(top_loc, AST::AST_DESIGN); + VerilogLexer lexer(&parse_state, &parse_mode, filename_shared); + frontend_verilog_yy::parser parser(&lexer, &parse_state, &parse_mode); + lexer.set_debug(flag_debug_lexer); + parser.set_debug_level(flag_debug_parser ? 1 : 0); + // make package typedefs available to parser add_package_types(parse_state.pkg_user_types, design->verilog_packages); diff --git a/frontends/verilog/verilog_lexer.h b/frontends/verilog/verilog_lexer.h index a4f3d9bfb..b7885181c 100644 --- a/frontends/verilog/verilog_lexer.h +++ b/frontends/verilog/verilog_lexer.h @@ -5,6 +5,7 @@ #include "frontends/ast/ast.h" #include "frontends/verilog/verilog_parser.tab.hh" #include +#include YOSYS_NAMESPACE_BEGIN @@ -15,7 +16,7 @@ namespace VERILOG_FRONTEND { ParseMode* mode; public: parser::location_type out_loc; // TODO private? - VerilogLexer(ParseState* e, ParseMode* m, std::string* filename) : frontend_verilog_yyFlexLexer(e->lexin), extra(e), mode(m) { + VerilogLexer(ParseState* e, ParseMode* m, std::shared_ptr filename) : frontend_verilog_yyFlexLexer(e->lexin), extra(e), mode(m) { out_loc.begin.filename = filename; } ~VerilogLexer() override {} @@ -27,7 +28,8 @@ namespace VERILOG_FRONTEND { return parser::make_FRONTEND_VERILOG_YYEOF(out_loc); } private: - std::vector fn_stack; + std::shared_ptr current_filename; + std::vector> fn_stack; std::vector ln_stack; int LexerInput(char* buf, int max_size) override { return readsome(*extra->lexin, buf, max_size); diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index f9e9dc2df..8e6e022b1 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -50,8 +50,10 @@ #include "frontends/verilog/verilog_lexer.h" #include "frontends/ast/ast.h" +#include "frontends/verilog/verilog_location.h" #include "kernel/log.h" #include +#include USING_YOSYS_NAMESPACE using namespace AST; @@ -73,7 +75,7 @@ YOSYS_NAMESPACE_END if (mode->sv) return _tok; \ log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\ "recognized unless read_verilog is called with -sv!\n", YYText(), \ - AST::current_filename.c_str(), yylineno); \ + current_filename->c_str(), yylineno); \ string_t val = std::make_unique(std::string("\\") + YYText()); \ return parser::make_TOK_ID(std::move(val), out_loc); @@ -85,16 +87,17 @@ YOSYS_NAMESPACE_END // result = readsome(*extra->lexin, buf, max_size) #define YY_USER_ACTION \ - out_loc.begin = out_loc.end; \ - for(int i = 0; YYText()[i] != '\0'; ++i){ \ - if(YYText()[i] == '\n') { \ - out_loc.end.line++; \ - out_loc.end.column = 1; \ - } \ - else { \ - out_loc.end.column++; \ - } \ - } + out_loc.step(); \ + for(int i = 0; YYText()[i] != '\0'; ++i){ \ + if(YYText()[i] == '\n') { \ + out_loc.lines(); \ + } \ + else { \ + out_loc.columns(); \ + } \ + } \ + out_loc.begin.filename = current_filename; \ + out_loc.end.filename = current_filename; #define YY_BREAK \ break; @@ -175,11 +178,12 @@ TIME_SCALE_SUFFIX [munpf]?s "`file_push "[^\n]* { fn_stack.push_back(current_filename); ln_stack.push_back(yylineno); - current_filename = YYText()+11; - if (!current_filename.empty() && current_filename.front() == '"') - current_filename = current_filename.substr(1); - if (!current_filename.empty() && current_filename.back() == '"') - current_filename = current_filename.substr(0, current_filename.size()-1); + std::string filename = YYText()+11; + if (!filename.empty() && filename.front() == '"') + filename = filename.substr(1); + if (!filename.empty() && filename.back() == '"') + filename = filename.substr(0, filename.size()-1); + current_filename = std::make_shared(filename); yylineno = (0); out_loc.begin.line = out_loc.end.line = 0; } @@ -201,7 +205,7 @@ TIME_SCALE_SUFFIX [munpf]?s while (*p == ' ' || *p == '\t') p++; const char *q = *p ? p + 1 : p; while (*q && *q != '"') q++; - current_filename = std::string(p).substr(1, q-p-1); + current_filename = std::make_shared(std::string(p).substr(1, q-p-1)); } "`file_notfound "[^\n]* { diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 527d01247..7ccf404f7 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -38,14 +38,17 @@ %define api.value.type variant %define api.prefix {frontend_verilog_yy} %define api.token.constructor +%define api.location.type {location} %param { YOSYS_NAMESPACE_PREFIX VERILOG_FRONTEND::VerilogLexer* lexer } %parse-param { YOSYS_NAMESPACE_PREFIX VERILOG_FRONTEND::ParseState* extra } %parse-param { YOSYS_NAMESPACE_PREFIX VERILOG_FRONTEND::ParseMode* mode } + %code requires { #include "kernel/yosys_common.h" #include "frontends/verilog/verilog_error.h" + #include "frontends/verilog/verilog_location.h" // start requires YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { @@ -101,10 +104,10 @@ const AstNode *addIncOrDecStmt(dict> *stmt_attr, std::unique_ptr lhs, dict> *op_attr, AST::AstNodeType op, - parser::location_type begin, parser::location_type end); - std::unique_ptr addIncOrDecExpr(std::unique_ptr lhs, dict> *attr, AST::AstNodeType op, parser::location_type begin, parser::location_type end, bool undo, bool sv_mode); + parser::location_type loc); + std::unique_ptr addIncOrDecExpr(std::unique_ptr lhs, dict> *attr, AST::AstNodeType op, parser::location_type loc, bool undo, bool sv_mode); // add a binary operator assignment statement, e.g., a += b - std::unique_ptr addAsgnBinopStmt(dict> *attr, std::unique_ptr eq_lhs, AST::AstNodeType op, std::unique_ptr rhs, parser::location_type begin, parser::location_type end); + std::unique_ptr addAsgnBinopStmt(dict> *attr, std::unique_ptr eq_lhs, AST::AstNodeType op, std::unique_ptr rhs); }; struct ParseMode { bool noassert = false; @@ -140,13 +143,7 @@ return lexer->nextToken(); } - #define SET_LOC(WHICH, BEGIN, END) \ - do { WHICH.first_line = (BEGIN).begin.line; \ - WHICH.first_column = (BEGIN).begin.column; \ - WHICH.last_line = (END).end.line; \ - WHICH.last_column = (END).end.column; } while(0) - - #define SET_AST_NODE_LOC(WHICH, BEGIN, END) SET_LOC((WHICH)->location, BEGIN, END) + #define SET_AST_NODE_LOC(WHICH, BEGIN, END) (WHICH)->location = location_range(BEGIN, END) #define SET_RULE_LOC(LHS, BEGIN, END) \ do { (LHS).begin = BEGIN.begin; \ @@ -154,10 +151,13 @@ YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { + + static location location_range(location begin, location end) { + return location(begin.begin, end.end); + } + static ConstParser make_ConstParser_here(parser::location_type flex_loc) { - AstSrcLocType loc; - SET_LOC(loc, flex_loc, flex_loc); - ConstParser p{loc}; + ConstParser p{flex_loc}; return p; } static void append_attr(AstNode *ast, dict> *al) @@ -180,18 +180,18 @@ delete al; } - static std::unique_ptr makeRange(int msb = 31, int lsb = 0, bool isSigned = true) + static std::unique_ptr makeRange(parser::location_type loc, int msb = 31, int lsb = 0, bool isSigned = true) { - auto range = std::make_unique(AST_RANGE); - range->children.push_back(AstNode::mkconst_int(msb, true)); - range->children.push_back(AstNode::mkconst_int(lsb, true)); + auto range = std::make_unique(loc, AST_RANGE); + range->children.push_back(AstNode::mkconst_int(loc, msb, true)); + range->children.push_back(AstNode::mkconst_int(loc, lsb, true)); range->is_signed = isSigned; return range; } static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned = true) { - auto range = makeRange(msb, lsb, isSigned); + auto range = makeRange(parent->location, msb, lsb, isSigned); parent->children.push_back(std::move(range)); } @@ -203,7 +203,7 @@ err_at_ast(type_node->location, "integer/genvar types cannot have packed dimensions."); } else { - range_node = makeRange(type_node->range_left, type_node->range_right, false); + range_node = makeRange(type_node->location, type_node->range_left, type_node->range_right, false); } } @@ -227,8 +227,8 @@ { if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) { // SV array size [n], rewrite as [0:n-1] - rangeNode->children.push_back(std::make_unique(AST_SUB, std::move(rangeNode->children[0]), AstNode::mkconst_int(1, true))); - rangeNode->children[0] = AstNode::mkconst_int(0, false); + rangeNode->children.push_back(std::make_unique(rangeNode->location, AST_SUB, std::move(rangeNode->children[0]), AstNode::mkconst_int(rangeNode->location, 1, true))); + rangeNode->children[0] = AstNode::mkconst_int(rangeNode->location, 0, false); } } @@ -268,14 +268,14 @@ { log_assert(node); node->is_custom_type = true; - node->children.push_back(std::make_unique(AST_WIRETYPE)); + node->children.push_back(std::make_unique(node->location, AST_WIRETYPE)); node->children.back()->str = *name; } void ParseState::addTypedefNode(std::string *name, std::unique_ptr node) { log_assert((bool)node); - AstNode* tnode = saveChild(std::make_unique(AST_TYPEDEF, std::move(node))); + AstNode* tnode = saveChild(std::make_unique(node->location, AST_TYPEDEF, std::move(node))); log_assert((bool)name); tnode->str = *name; auto &user_types = user_type_stack.back(); @@ -342,9 +342,9 @@ // create a new localparam with old name so that the items in the loop // can simply use the old name and shadow it as necessary - auto indirect = std::make_unique(AST_LOCALPARAM); + auto indirect = std::make_unique(loop->location, AST_LOCALPARAM); indirect->str = old_str; - auto ident = std::make_unique(AST_IDENTIFIER); + auto ident = std::make_unique(loop->location, AST_IDENTIFIER); ident->str = new_str; indirect->children.push_back(std::move(ident)); @@ -376,54 +376,48 @@ const AstNode *ParseState::addIncOrDecStmt(dict> *stmt_attr, std::unique_ptr lhs, dict> *op_attr, AST::AstNodeType op, - frontend_verilog_yy::location begin, frontend_verilog_yy::location end) + location loc) { - auto one = AstNode::mkconst_int(1, true); - auto rhs = std::make_unique(op, lhs->clone(), std::move(one)); + auto one = AstNode::mkconst_int(loc, 1, true); + auto rhs = std::make_unique(loc, op, lhs->clone(), std::move(one)); if (op_attr != nullptr) append_attr(rhs.get(), op_attr); - auto stmt_owned = std::make_unique(AST_ASSIGN_EQ, std::move(lhs), std::move(rhs)); + auto stmt_owned = std::make_unique(loc, AST_ASSIGN_EQ, std::move(lhs), std::move(rhs)); auto* stmt = stmt_owned.get(); ast_stack.back()->children.push_back(std::move(stmt_owned)); - SET_AST_NODE_LOC(stmt, begin, end); if (stmt_attr != nullptr) append_attr(stmt, stmt_attr); return stmt; } // create a pre/post-increment/decrement expression, and add the corresponding statement - std::unique_ptr ParseState::addIncOrDecExpr(std::unique_ptr lhs, dict> *attr, AST::AstNodeType op, frontend_verilog_yy::location begin, frontend_verilog_yy::location end, bool undo, bool sv_mode) + std::unique_ptr ParseState::addIncOrDecExpr(std::unique_ptr lhs, dict> *attr, AST::AstNodeType op, location loc, bool undo, bool sv_mode) { - ensureAsgnExprAllowed(begin, sv_mode); - const AstNode *stmt = addIncOrDecStmt(nullptr, std::move(lhs), attr, op, begin, end); + ensureAsgnExprAllowed(loc, sv_mode); + const AstNode *stmt = addIncOrDecStmt(nullptr, std::move(lhs), attr, op, loc); log_assert(stmt->type == AST_ASSIGN_EQ); auto expr = stmt->children[0]->clone(); if (undo) { - auto one = AstNode::mkconst_int(1, false, 1); - auto minus_one = std::make_unique(AST_NEG, std::move(one)); - expr = std::make_unique(op, std::move(expr), std::move(minus_one)); + auto one = AstNode::mkconst_int(loc, 1, false, 1); + auto minus_one = std::make_unique(loc, AST_NEG, std::move(one)); + expr = std::make_unique(loc, op, std::move(expr), std::move(minus_one)); } - SET_AST_NODE_LOC(expr.get(), begin, end); return expr; } // add a binary operator assignment statement, e.g., a += b - std::unique_ptr ParseState::addAsgnBinopStmt(dict> *attr, std::unique_ptr eq_lhs, AST::AstNodeType op, std::unique_ptr rhs, frontend_verilog_yy::location begin, frontend_verilog_yy::location end) + std::unique_ptr ParseState::addAsgnBinopStmt(dict> *attr, std::unique_ptr eq_lhs, AST::AstNodeType op, std::unique_ptr rhs) { - SET_AST_NODE_LOC(rhs.get(), end, end); + location loc = location_range(eq_lhs->location, rhs->location); if (op == AST_SHIFT_LEFT || op == AST_SHIFT_RIGHT || op == AST_SHIFT_SLEFT || op == AST_SHIFT_SRIGHT) { - rhs = std::make_unique(AST_TO_UNSIGNED, std::move(rhs)); - SET_AST_NODE_LOC(rhs.get(), end, end); + rhs = std::make_unique(rhs->location, AST_TO_UNSIGNED, std::move(rhs)); } auto binop_lhs = eq_lhs->clone(); - auto eq_rhs_owned = std::make_unique(op, std::move(binop_lhs), std::move(rhs)); - auto* eq_rhs = eq_rhs_owned.get(); + auto eq_rhs_owned = std::make_unique(loc, op, std::move(binop_lhs), std::move(rhs)); auto ret_lhs = eq_lhs->clone(); - auto stmt_owned = std::make_unique(AST_ASSIGN_EQ, std::move(eq_lhs), std::move(eq_rhs_owned)); + auto stmt_owned = std::make_unique(loc, AST_ASSIGN_EQ, std::move(eq_lhs), std::move(eq_rhs_owned)); auto* stmt = stmt_owned.get(); - SET_AST_NODE_LOC(eq_rhs, begin, end); - SET_AST_NODE_LOC(stmt, begin, end); ast_stack.back()->children.push_back(std::move(stmt_owned)); if (attr != nullptr) append_attr(stmt, attr); @@ -675,7 +669,7 @@ attr_list: attr_assign: hierarchical_id { - (*extra->attr_list)[*$1] = AstNode::mkconst_int(1, false); + (*extra->attr_list)[*$1] = AstNode::mkconst_int(@1, 1, false); } | hierarchical_id TOK_EQ expr { (*extra->attr_list)[*$1] = std::move($3); @@ -711,7 +705,7 @@ module: extra->enterTypeScope(); } TOK_ID { extra->do_not_require_port_stubs = false; - AstNode* mod = extra->pushChild(std::make_unique(AST_MODULE)); + AstNode* mod = extra->pushChild(std::make_unique(@$, AST_MODULE)); extra->current_ast_mod = mod; extra->port_stubs.clear(); extra->port_counter = 0; @@ -738,13 +732,13 @@ module_para_list: single_module_para: %empty | attr TOK_PARAMETER { - extra->astbuf1 = std::make_unique(AST_PARAMETER); - extra->astbuf1->children.push_back(AstNode::mkconst_int(0, true)); + extra->astbuf1 = std::make_unique(@$, AST_PARAMETER); + extra->astbuf1->children.push_back(AstNode::mkconst_int(@2, 0, true)); append_attr(extra->astbuf1.get(), $1); } param_type single_param_decl | attr TOK_LOCALPARAM { - extra->astbuf1 = std::make_unique(AST_LOCALPARAM); - extra->astbuf1->children.push_back(AstNode::mkconst_int(0, true)); + extra->astbuf1 = std::make_unique(@$, AST_LOCALPARAM); + extra->astbuf1->children.push_back(AstNode::mkconst_int(@2, 0, true)); append_attr(extra->astbuf1.get(), $1); } param_type single_param_decl | single_param_decl; @@ -765,12 +759,12 @@ module_arg_opt_assignment: auto& n = extra->ast_stack.back()->children.back(); n->attributes[ID::defaultvalue] = std::move($2); } else { - auto wire = std::make_unique(AST_IDENTIFIER); + auto wire = std::make_unique(@$, AST_IDENTIFIER); wire->str = extra->ast_stack.back()->children.back()->str; if (extra->ast_stack.back()->children.back()->is_reg || extra->ast_stack.back()->children.back()->is_logic) - extra->ast_stack.back()->children.push_back(std::make_unique(AST_INITIAL, std::make_unique(AST_BLOCK, std::make_unique(AST_ASSIGN_LE, std::move(wire), std::move($2))))); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_INITIAL, std::make_unique(@$, AST_BLOCK, std::make_unique(@$, AST_ASSIGN_LE, std::move(wire), std::move($2))))); else - extra->ast_stack.back()->children.push_back(std::make_unique(AST_ASSIGN, std::move(wire), std::move($2))); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_ASSIGN, std::move(wire), std::move($2))); } } else err_at_loc(@2, "SystemVerilog interface in module port list cannot have a default value."); @@ -792,8 +786,8 @@ module_arg: } } module_arg_opt_assignment | TOK_ID { - extra->astbuf1 = std::make_unique(AST_INTERFACEPORT); - extra->astbuf1->children.push_back(std::make_unique(AST_INTERFACEPORTTYPE)); + extra->astbuf1 = std::make_unique(@$, AST_INTERFACEPORT); + extra->astbuf1->children.push_back(std::make_unique(@$, AST_INTERFACEPORTTYPE)); extra->astbuf1->children[0]->str = *$1; } TOK_ID { /* SV interfaces */ if (!mode->sv) @@ -826,7 +820,7 @@ package: attr TOK_PACKAGE { extra->enterTypeScope(); } TOK_ID { - AstNode* mod = extra->pushChild(std::make_unique(AST_PACKAGE)); + AstNode* mod = extra->pushChild(std::make_unique(@$, AST_PACKAGE)); extra->current_ast_mod = mod; mod->str = *$4; append_attr(mod, $1); @@ -848,7 +842,7 @@ interface: extra->enterTypeScope(); } TOK_ID { extra->do_not_require_port_stubs = false; - AstNode* intf = extra->pushChild(std::make_unique(AST_INTERFACE)); + AstNode* intf = extra->pushChild(std::make_unique(@$, AST_INTERFACE)); extra->current_ast_mod = intf; extra->port_stubs.clear(); extra->port_counter = 0; @@ -872,7 +866,7 @@ interface_body_stmt: bind_directive: TOK_BIND { - (void)extra->pushChild(std::make_unique(AST_BIND)); + (void)extra->pushChild(std::make_unique(@$, AST_BIND)); } bind_target { // bind_target should have added at least one child @@ -881,8 +875,8 @@ bind_directive: TOK_ID { // The single_cell parser in cell_list_no_array uses extra->astbuf1 as // a sort of template for constructing cells. - extra->astbuf1 = std::make_unique(AST_CELL); - extra->astbuf1->children.push_back(std::make_unique(AST_CELLTYPE)); + extra->astbuf1 = std::make_unique(@$, AST_CELL); + extra->astbuf1->children.push_back(std::make_unique(@$, AST_CELLTYPE)); extra->astbuf1->children[0]->str = *$5; } cell_parameter_list_opt cell_list_no_array TOK_SEMICOL { @@ -921,7 +915,7 @@ bind_target_instance_list: // the bind node where we should add it. bind_target_instance: hierarchical_id { - auto node = std::make_unique(AST_IDENTIFIER); + auto node = std::make_unique(@$, AST_IDENTIFIER); node->str = *$1; extra->ast_stack.back()->children.push_back(std::move(node)); }; @@ -945,12 +939,12 @@ delay: non_opt_delay | %empty; io_wire_type: - { extra->astbuf3 = std::make_unique(AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } + { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness { $$ = std::move(extra->astbuf3); SET_RULE_LOC(@$, @2, @$); }; non_io_wire_type: - { extra->astbuf3 = std::make_unique(AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } + { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } wire_type_const_rand wire_type_token wire_type_signedness { $$ = std::move(extra->astbuf3); SET_RULE_LOC(@$, @2, @$); }; @@ -1056,30 +1050,30 @@ integer_vector_type: non_opt_range: TOK_LBRA expr TOK_COL expr TOK_RBRA { - $$ = std::make_unique(AST_RANGE); + $$ = std::make_unique(@$, AST_RANGE); $$->children.push_back(std::move($2)); $$->children.push_back(std::move($4)); } | TOK_LBRA expr TOK_POS_INDEXED expr TOK_RBRA { - $$ = std::make_unique(AST_RANGE); - auto expr = std::make_unique(AST_SELFSZ, std::move($2)); - $$->children.push_back(std::make_unique(AST_SUB, std::make_unique(AST_ADD, expr->clone(), std::move($4)), AstNode::mkconst_int(1, true))); - $$->children.push_back(std::make_unique(AST_ADD, std::move(expr), AstNode::mkconst_int(0, true))); + $$ = std::make_unique(@$, AST_RANGE); + auto expr = std::make_unique(@$, AST_SELFSZ, std::move($2)); + $$->children.push_back(std::make_unique(@$, AST_SUB, std::make_unique(@$, AST_ADD, expr->clone(), std::move($4)), AstNode::mkconst_int(@$, 1, true))); + $$->children.push_back(std::make_unique(@$, AST_ADD, std::move(expr), AstNode::mkconst_int(@$, 0, true))); } | TOK_LBRA expr TOK_NEG_INDEXED expr TOK_RBRA { - $$ = std::make_unique(AST_RANGE); - auto expr = std::make_unique(AST_SELFSZ, std::move($2)); - $$->children.push_back(std::make_unique(AST_ADD, expr->clone(), AstNode::mkconst_int(0, true))); - $$->children.push_back(std::make_unique(AST_SUB, std::make_unique(AST_ADD, std::move(expr), AstNode::mkconst_int(1, true)), std::move($4))); + $$ = std::make_unique(@$, AST_RANGE); + auto expr = std::make_unique(@$, AST_SELFSZ, std::move($2)); + $$->children.push_back(std::make_unique(@$, AST_ADD, expr->clone(), AstNode::mkconst_int(@$, 0, true))); + $$->children.push_back(std::make_unique(@$, AST_SUB, std::make_unique(@$, AST_ADD, std::move(expr), AstNode::mkconst_int(@$, 1, true)), std::move($4))); } | TOK_LBRA expr TOK_RBRA { - $$ = std::make_unique(AST_RANGE); + $$ = std::make_unique(@$, AST_RANGE); $$->children.push_back(std::move($2)); }; non_opt_multirange: non_opt_range non_opt_range { - $$ = std::make_unique(AST_MULTIRANGE, std::move($1), std::move($2)); + $$ = std::make_unique(@$, AST_MULTIRANGE, std::move($1), std::move($2)); } | non_opt_multirange non_opt_range { $$ = std::move($1); @@ -1113,7 +1107,7 @@ module_body_stmt: checker_decl: TOK_CHECKER TOK_ID TOK_SEMICOL { - AstNode* node = extra->pushChild(std::make_unique(AST_GENBLOCK)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_GENBLOCK)); node->str = *$2; } module_body TOK_ENDCHECKER { extra->ast_stack.pop_back(); @@ -1121,28 +1115,28 @@ checker_decl: task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { - extra->current_function_or_task = extra->saveChild(std::make_unique(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4))); + extra->current_function_or_task = extra->saveChild(std::make_unique(@$, AST_DPI_FUNCTION, AstNode::mkconst_str(@3, *$3), AstNode::mkconst_str(@4, *$4))); extra->current_function_or_task->str = *$4; append_attr(extra->current_function_or_task, $1); } opt_dpi_function_args TOK_SEMICOL { extra->current_function_or_task = nullptr; } | attr TOK_DPI_FUNCTION TOK_ID TOK_EQ TOK_ID TOK_ID { - extra->current_function_or_task = extra->saveChild(std::make_unique(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3))); + extra->current_function_or_task = extra->saveChild(std::make_unique(@$, AST_DPI_FUNCTION, AstNode::mkconst_str(@5, *$5), AstNode::mkconst_str(@3, *$3))); extra->current_function_or_task->str = *$6; append_attr(extra->current_function_or_task, $1); } opt_dpi_function_args TOK_SEMICOL { extra->current_function_or_task = nullptr; } | attr TOK_DPI_FUNCTION TOK_ID TOK_COL TOK_ID TOK_EQ TOK_ID TOK_ID { - extra->current_function_or_task = extra->saveChild(std::make_unique(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5)))); + extra->current_function_or_task = extra->saveChild(std::make_unique(@$, AST_DPI_FUNCTION, AstNode::mkconst_str(@7, *$7), AstNode::mkconst_str(location_range(@3, @5), *$3 + ":" + RTLIL::unescape_id(*$5)))); extra->current_function_or_task->str = *$8; append_attr(extra->current_function_or_task, $1); } opt_dpi_function_args TOK_SEMICOL { extra->current_function_or_task = nullptr; } | attr TOK_TASK opt_automatic TOK_ID { - extra->current_function_or_task = extra->pushChild(std::make_unique(AST_TASK)); + extra->current_function_or_task = extra->pushChild(std::make_unique(@$, AST_TASK)); extra->current_function_or_task->str = *$4; append_attr(extra->current_function_or_task, $1); extra->current_function_or_task_port_id = 1; @@ -1156,7 +1150,7 @@ task_func_decl: // inlined, but ignores signals read only in tasks. This only matters // for event based simulation, and for synthesis we can treat a void // function like a task. - extra->current_function_or_task = extra->pushChild(std::make_unique(AST_TASK)); + extra->current_function_or_task = extra->pushChild(std::make_unique(@$, AST_TASK)); extra->current_function_or_task->str = *$5; append_attr(extra->current_function_or_task, $1); extra->current_function_or_task_port_id = 1; @@ -1165,10 +1159,10 @@ task_func_decl: extra->ast_stack.pop_back(); } | attr TOK_FUNCTION opt_automatic func_return_type TOK_ID { - extra->current_function_or_task = extra->pushChild(std::make_unique(AST_FUNCTION)); + extra->current_function_or_task = extra->pushChild(std::make_unique(@$, AST_FUNCTION)); extra->current_function_or_task->str = *$5; append_attr(extra->current_function_or_task, $1); - auto outreg = std::make_unique(AST_WIRE); + auto outreg = std::make_unique(@$, AST_WIRE); outreg->str = *$5; outreg->is_signed = false; outreg->is_reg = true; @@ -1187,18 +1181,18 @@ task_func_decl: func_return_type: hierarchical_type_id { - $$ = std::make_unique(AST_WIRETYPE); + $$ = std::make_unique(@$, AST_WIRETYPE); $$->str = *$1; } | opt_type_vec opt_signedness_default_unsigned { - $$ = makeRange(0, 0, $2); + $$ = makeRange(@$, 0, 0, $2); } | opt_type_vec opt_signedness_default_unsigned non_opt_range { $$ = std::move($3); $$->is_signed = $2; } | integer_atom_type opt_signedness_default_signed { - $$ = makeRange($1 - 1, 0, $2); + $$ = makeRange(@$, $1 - 1, 0, $2); }; opt_type_vec: @@ -1220,10 +1214,10 @@ opt_signedness_default_unsigned: dpi_function_arg: TOK_ID TOK_ID { - extra->current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + extra->current_function_or_task->children.push_back(AstNode::mkconst_str(@1, *$1)); } | TOK_ID { - extra->current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + extra->current_function_or_task->children.push_back(AstNode::mkconst_str(@1, *$1)); }; opt_dpi_function_args: @@ -1282,7 +1276,7 @@ task_func_port: if (!mode->sv) err_at_loc(@$, "task/function argument direction missing"); extra->albuf = new dict>; - extra->astbuf1 = std::make_unique(AST_WIRE); + extra->astbuf1 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; extra->astbuf1->is_input = true; @@ -1315,11 +1309,11 @@ specify_item: if (specify_edge != 0 && target->dat == nullptr) err_at_loc(@3, "Found specify edge but no data spec.\n"); - auto cell_owned = std::make_unique(AST_CELL); + auto cell_owned = std::make_unique(@$, AST_CELL); auto cell = cell_owned.get(); extra->ast_stack.back()->children.push_back(std::move(cell_owned)); cell->str = stringf("$specify$%d", autoidx++); - cell->children.push_back(std::make_unique(AST_CELLTYPE)); + cell->children.push_back(std::make_unique(@$, AST_CELLTYPE)); cell->children.back()->str = target->dat ? "$specify3" : "$specify2"; SET_AST_NODE_LOC(cell, en_expr.get() ? @1 : @2, @10); @@ -1331,57 +1325,57 @@ specify_item: oper_type = oper->at(1); } - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(oper_type == '*', false, 1))); + cell->children.push_back(std::make_unique(@5, AST_PARASET, AstNode::mkconst_int(@5, oper_type == '*', false, 1))); cell->children.back()->str = "\\FULL"; - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(oper_polarity != 0, false, 1))); + cell->children.push_back(std::make_unique(@5, AST_PARASET, AstNode::mkconst_int(@5, oper_polarity != 0, false, 1))); cell->children.back()->str = "\\SRC_DST_PEN"; - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(oper_polarity == '+', false, 1))); + cell->children.push_back(std::make_unique(@5, AST_PARASET, AstNode::mkconst_int(@5, oper_polarity == '+', false, 1))); cell->children.back()->str = "\\SRC_DST_POL"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->rise.t_min))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->rise.t_min))); cell->children.back()->str = "\\T_RISE_MIN"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->rise.t_avg))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->rise.t_avg))); cell->children.back()->str = "\\T_RISE_TYP"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->rise.t_max))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->rise.t_max))); cell->children.back()->str = "\\T_RISE_MAX"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->fall.t_min))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->fall.t_min))); cell->children.back()->str = "\\T_FALL_MIN"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->fall.t_avg))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->fall.t_avg))); cell->children.back()->str = "\\T_FALL_TYP"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(timing->fall.t_max))); + cell->children.push_back(std::make_unique(@9, AST_PARASET, std::move(timing->fall.t_max))); cell->children.back()->str = "\\T_FALL_MAX"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, en_expr ? std::move(en_expr) : AstNode::mkconst_int(1, false, 1))); + cell->children.push_back(std::make_unique(@1, AST_ARGUMENT, en_expr ? std::move(en_expr) : AstNode::mkconst_int(@1, 1, false, 1))); cell->children.back()->str = "\\EN"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(src_expr))); + cell->children.push_back(std::make_unique(@4, AST_ARGUMENT, std::move(src_expr))); cell->children.back()->str = "\\SRC"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(target->dst))); + cell->children.push_back(std::make_unique(@6, AST_ARGUMENT, std::move(target->dst))); cell->children.back()->str = "\\DST"; if (target->dat) { - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(specify_edge != 0, false, 1))); + cell->children.push_back(std::make_unique(@3, AST_PARASET, AstNode::mkconst_int(@3, specify_edge != 0, false, 1))); cell->children.back()->str = "\\EDGE_EN"; - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(specify_edge == 'p', false, 1))); + cell->children.push_back(std::make_unique(@3, AST_PARASET, AstNode::mkconst_int(@3, specify_edge == 'p', false, 1))); cell->children.back()->str = "\\EDGE_POL"; - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(target->polarity_op != 0, false, 1))); + cell->children.push_back(std::make_unique(@6, AST_PARASET, AstNode::mkconst_int(@6, target->polarity_op != 0, false, 1))); cell->children.back()->str = "\\DAT_DST_PEN"; - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_int(target->polarity_op == '+', false, 1))); + cell->children.push_back(std::make_unique(@6, AST_PARASET, AstNode::mkconst_int(@6, target->polarity_op == '+', false, 1))); cell->children.back()->str = "\\DAT_DST_POL"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(target->dat))); + cell->children.push_back(std::make_unique(@6, AST_ARGUMENT, std::move(target->dat))); cell->children.back()->str = "\\DAT"; } } | @@ -1390,68 +1384,68 @@ specify_item: *$1 != "$recrem" && *$1 != "$skew" && *$1 != "$timeskew" && *$1 != "$fullskew" && *$1 != "$nochange") err_at_loc(@1, "Unsupported specify rule type: %s\n", $1->c_str()); - auto src_pen = AstNode::mkconst_int($3 != 0, false, 1); - auto src_pol = AstNode::mkconst_int($3 == 'p', false, 1); - auto src_expr = std::move($4), src_en = $5 ? std::move($5) : AstNode::mkconst_int(1, false, 1); + auto src_pen = AstNode::mkconst_int(@3, $3 != 0, false, 1); + auto src_pol = AstNode::mkconst_int(@3, $3 == 'p', false, 1); + auto src_expr = std::move($4), src_en = $5 ? std::move($5) : AstNode::mkconst_int(@5, 1, false, 1); - auto dst_pen = AstNode::mkconst_int($7 != 0, false, 1); - auto dst_pol = AstNode::mkconst_int($7 == 'p', false, 1); - auto dst_expr = std::move($8), dst_en = $9 ? std::move($9) : AstNode::mkconst_int(1, false, 1); + auto dst_pen = AstNode::mkconst_int(@7, $7 != 0, false, 1); + auto dst_pol = AstNode::mkconst_int(@7, $7 == 'p', false, 1); + auto dst_expr = std::move($8), dst_en = $9 ? std::move($9) : AstNode::mkconst_int(@5, 1, false, 1); specify_triple_ptr_t limit = std::move($11); specify_triple_ptr_t limit2 = std::move($12); - auto cell_owned = std::make_unique(AST_CELL); + auto cell_owned = std::make_unique(@$, AST_CELL); auto cell = cell_owned.get(); extra->ast_stack.back()->children.push_back(std::move(cell_owned)); cell->str = stringf("$specify$%d", autoidx++); - cell->children.push_back(std::make_unique(AST_CELLTYPE)); + cell->children.push_back(std::make_unique(@$, AST_CELLTYPE)); cell->children.back()->str = "$specrule"; SET_AST_NODE_LOC(cell, @1, @14); - cell->children.push_back(std::make_unique(AST_PARASET, AstNode::mkconst_str(*$1))); + cell->children.push_back(std::make_unique(@1, AST_PARASET, AstNode::mkconst_str(@1, *$1))); cell->children.back()->str = "\\TYPE"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(limit->t_min))); + cell->children.push_back(std::make_unique(@11, AST_PARASET, std::move(limit->t_min))); cell->children.back()->str = "\\T_LIMIT_MIN"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(limit->t_avg))); + cell->children.push_back(std::make_unique(@11, AST_PARASET, std::move(limit->t_avg))); cell->children.back()->str = "\\T_LIMIT_TYP"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(limit->t_max))); + cell->children.push_back(std::make_unique(@11, AST_PARASET, std::move(limit->t_max))); cell->children.back()->str = "\\T_LIMIT_MAX"; - cell->children.push_back(std::make_unique(AST_PARASET, limit2 ? std::move(limit2->t_min) : AstNode::mkconst_int(0, true))); + cell->children.push_back(std::make_unique(@12, AST_PARASET, limit2 ? std::move(limit2->t_min) : AstNode::mkconst_int(@12, 0, true))); cell->children.back()->str = "\\T_LIMIT2_MIN"; - cell->children.push_back(std::make_unique(AST_PARASET, limit2 ? std::move(limit2->t_avg) : AstNode::mkconst_int(0, true))); + cell->children.push_back(std::make_unique(@12, AST_PARASET, limit2 ? std::move(limit2->t_avg) : AstNode::mkconst_int(@12, 0, true))); cell->children.back()->str = "\\T_LIMIT2_TYP"; - cell->children.push_back(std::make_unique(AST_PARASET, limit2 ? std::move(limit2->t_max) : AstNode::mkconst_int(0, true))); + cell->children.push_back(std::make_unique(@12, AST_PARASET, limit2 ? std::move(limit2->t_max) : AstNode::mkconst_int(@12, 0, true))); cell->children.back()->str = "\\T_LIMIT2_MAX"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(src_pen))); + cell->children.push_back(std::make_unique(@3, AST_PARASET, std::move(src_pen))); cell->children.back()->str = "\\SRC_PEN"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(src_pol))); + cell->children.push_back(std::make_unique(@3, AST_PARASET, std::move(src_pol))); cell->children.back()->str = "\\SRC_POL"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(dst_pen))); + cell->children.push_back(std::make_unique(@3, AST_PARASET, std::move(dst_pen))); cell->children.back()->str = "\\DST_PEN"; - cell->children.push_back(std::make_unique(AST_PARASET, std::move(dst_pol))); + cell->children.push_back(std::make_unique(@7, AST_PARASET, std::move(dst_pol))); cell->children.back()->str = "\\DST_POL"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(src_en))); + cell->children.push_back(std::make_unique(@5, AST_ARGUMENT, std::move(src_en))); cell->children.back()->str = "\\SRC_EN"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(src_expr))); + cell->children.push_back(std::make_unique(@4, AST_ARGUMENT, std::move(src_expr))); cell->children.back()->str = "\\SRC"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(dst_en))); + cell->children.push_back(std::make_unique(@9, AST_ARGUMENT, std::move(dst_en))); cell->children.back()->str = "\\DST_EN"; - cell->children.push_back(std::make_unique(AST_ARGUMENT, std::move(dst_expr))); + cell->children.push_back(std::make_unique(@8, AST_ARGUMENT, std::move(dst_expr))); cell->children.back()->str = "\\DST"; }; @@ -1527,19 +1521,19 @@ specify_rise_fall: $$ = std::make_unique(); $$->rise = std::move(*$2); $$->fall = std::move(*$4); - log_file_warning(current_filename, @$.begin.line, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); + err_at_loc(@$, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); } | TOK_LPAREN specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_RPAREN { $$ = std::make_unique(); $$->rise = std::move(*$2); $$->fall = std::move(*$4); - log_file_warning(current_filename, @$.begin.line, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); + err_at_loc(@$, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); } | TOK_LPAREN specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_COMMA specify_triple TOK_RPAREN { $$ = std::make_unique(); $$->rise = std::move(*$2); $$->fall = std::move(*$4); - log_file_warning(current_filename, @$.begin.line, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); + err_at_loc(@$, "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n"); } specify_triple: @@ -1697,7 +1691,7 @@ param_integer: param_real: TOK_REAL { - extra->astbuf1->children.push_back(std::make_unique(AST_REALVALUE)); + extra->astbuf1->children.push_back(std::make_unique(@$, AST_REALVALUE)); }; param_range: @@ -1725,8 +1719,8 @@ param_type: param_decl: attr TOK_PARAMETER { - extra->astbuf1 = std::make_unique(AST_PARAMETER); - extra->astbuf1->children.push_back(AstNode::mkconst_int(0, true)); + extra->astbuf1 = std::make_unique(@$, AST_PARAMETER); + extra->astbuf1->children.push_back(AstNode::mkconst_int(@$, 0, true)); append_attr(extra->astbuf1.get(), $1); } param_type param_decl_list TOK_SEMICOL { (void)extra->astbuf1.reset(); @@ -1734,8 +1728,8 @@ param_decl: localparam_decl: attr TOK_LOCALPARAM { - extra->astbuf1 = std::make_unique(AST_LOCALPARAM); - extra->astbuf1->children.push_back(AstNode::mkconst_int(0, true)); + extra->astbuf1 = std::make_unique(@$, AST_LOCALPARAM); + extra->astbuf1->children.push_back(AstNode::mkconst_int(@$, 0, true)); append_attr(extra->astbuf1.get(), $1); } param_type param_decl_list TOK_SEMICOL { (void)extra->astbuf1.reset(); @@ -1767,8 +1761,8 @@ single_param_decl_ident: if (extra->astbuf1 == nullptr) { if (!mode->sv) err_at_loc(@1, "In pure Verilog (not SystemVerilog), parameter/localparam with an initializer must use the parameter/localparam keyword"); - node_owned = std::make_unique(AST_PARAMETER); - node_owned->children.push_back(AstNode::mkconst_int(0, true)); + node_owned = std::make_unique(@$, AST_PARAMETER); + node_owned->children.push_back(AstNode::mkconst_int(@$, 0, true)); } else { node_owned = extra->astbuf1->clone(); } @@ -1786,7 +1780,7 @@ defparam_decl_list: single_defparam_decl: range rvalue TOK_EQ expr { - auto node = std::make_unique(AST_DEFPARAM); + auto node = std::make_unique(@$, AST_DEFPARAM); node->children.push_back(std::move($2)); node->children.push_back(std::move($4)); if ($1 != nullptr) @@ -1801,15 +1795,15 @@ single_defparam_decl: enum_type: TOK_ENUM { static int enum_count; // create parent node for the enum - extra->astbuf2 = std::make_unique(AST_ENUM); + extra->astbuf2 = std::make_unique(@$, AST_ENUM); extra->astbuf2->str = std::string("$enum"); extra->astbuf2->str += std::to_string(enum_count++); log_assert(!extra->cell_hack); extra->cell_hack = extra->astbuf2.get(); extra->ast_stack.back()->children.push_back(std::move(extra->astbuf2)); // create the template for the names - extra->astbuf1 = std::make_unique(AST_ENUM_ITEM); - extra->astbuf1->children.push_back(AstNode::mkconst_int(0, true)); + extra->astbuf1 = std::make_unique(@$, AST_ENUM_ITEM); + extra->astbuf1->children.push_back(AstNode::mkconst_int(@$, 0, true)); } enum_base_type TOK_LCURL enum_name_list optional_comma TOK_RCURL { // create template for the enum vars log_assert(extra->cell_hack); @@ -1817,7 +1811,7 @@ enum_type: TOK_ENUM { auto* tnode = tnode_owned.get(); extra->astbuf1 = std::move(tnode_owned); tnode->type = AST_WIRE; - tnode->attributes[ID::enum_type] = AstNode::mkconst_str(extra->cell_hack->str); + tnode->attributes[ID::enum_type] = AstNode::mkconst_str(@$, extra->cell_hack->str); extra->cell_hack = nullptr; // drop constant but keep any range tnode->children.erase(tnode->children.begin()); @@ -1858,7 +1852,7 @@ enum_name_decl: auto node = extra->astbuf1->clone(); node->str = *$1; SET_AST_NODE_LOC(node.get(), @1, @1); - node->children[0] = $2 ? std::move($2) : std::make_unique(AST_NONE); + node->children[0] = $2 ? std::move($2) : std::make_unique(@$, AST_NONE); extra->cell_hack->children.push_back(std::move(node)); } ; @@ -1908,8 +1902,8 @@ struct_type: ; struct_union: - TOK_STRUCT { $$ = std::make_unique(AST_STRUCT); } - | TOK_UNION { $$ = std::make_unique(AST_UNION); } + TOK_STRUCT { $$ = std::make_unique(@$, AST_STRUCT); } + | TOK_UNION { $$ = std::make_unique(@$, AST_UNION); } ; struct_body: opt_packed TOK_LCURL struct_member_list TOK_RCURL @@ -1951,7 +1945,7 @@ member_name: TOK_ID { } ; -struct_member_type: { extra->astbuf1 = std::make_unique(AST_STRUCT_ITEM); } member_type_token +struct_member_type: { extra->astbuf1 = std::make_unique(@$, AST_STRUCT_ITEM); } member_type_token ; member_type_token: @@ -2008,17 +2002,17 @@ wire_decl: free_attr(extra->albuf); } TOK_SEMICOL | attr TOK_SUPPLY0 TOK_ID { - extra->ast_stack.back()->children.push_back(std::make_unique(AST_WIRE)); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_WIRE)); extra->ast_stack.back()->children.back()->str = *$3; append_attr(extra->ast_stack.back()->children.back().get(), $1); - extra->ast_stack.back()->children.push_back(std::make_unique(AST_ASSIGN, std::make_unique(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1))); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_ASSIGN, std::make_unique(@$, AST_IDENTIFIER), AstNode::mkconst_int(@$, 0, false, 1))); extra->ast_stack.back()->children.back()->children[0]->str = *$3; } opt_supply_wires TOK_SEMICOL | attr TOK_SUPPLY1 TOK_ID { - extra->ast_stack.back()->children.push_back(std::make_unique(AST_WIRE)); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_WIRE)); extra->ast_stack.back()->children.back()->str = *$3; append_attr(extra->ast_stack.back()->children.back().get(), $1); - extra->ast_stack.back()->children.push_back(std::make_unique(AST_ASSIGN, std::make_unique(AST_IDENTIFIER), AstNode::mkconst_int(1, false, 1))); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_ASSIGN, std::make_unique(@$, AST_IDENTIFIER), AstNode::mkconst_int(@$, 1, false, 1))); extra->ast_stack.back()->children.back()->children[0]->str = *$3; } opt_supply_wires TOK_SEMICOL; @@ -2059,8 +2053,8 @@ wire_name_and_opt_assign: attr_allseq = true; } if (extra->current_wire_rand || attr_anyconst || attr_anyseq || attr_allconst || attr_allseq) { - auto wire = std::make_unique(AST_IDENTIFIER); - auto fcall = std::make_unique(AST_FCALL); + auto wire = std::make_unique(@$, AST_IDENTIFIER); + auto fcall = std::make_unique(@$, AST_FCALL); wire->str = extra->ast_stack.back()->children.back()->str; fcall->str = extra->current_wire_const ? "\\$anyconst" : "\\$anyseq"; if (attr_anyconst) @@ -2071,28 +2065,28 @@ wire_name_and_opt_assign: fcall->str = "\\$allconst"; if (attr_allseq) fcall->str = "\\$allseq"; - fcall->attributes[ID::reg] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str)); - extra->ast_stack.back()->children.push_back(std::make_unique(AST_ASSIGN, std::move(wire), std::move(fcall))); + fcall->attributes[ID::reg] = AstNode::mkconst_str(@$, RTLIL::unescape_id(wire->str)); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_ASSIGN, std::move(wire), std::move(fcall))); } } | wire_name TOK_EQ expr { - auto wire = std::make_unique(AST_IDENTIFIER); + auto wire = std::make_unique(@$, AST_IDENTIFIER); wire->str = extra->ast_stack.back()->children.back()->str; if (extra->astbuf1->is_input) { extra->astbuf1->attributes[ID::defaultvalue] = std::move($3); } else if (extra->astbuf1->is_reg || extra->astbuf1->is_logic){ - auto assign = std::make_unique(AST_ASSIGN_LE, std::move(wire), std::move($3)); + auto assign = std::make_unique(@$, AST_ASSIGN_LE, std::move(wire), std::move($3)); SET_AST_NODE_LOC(assign.get(), @1, @3); - auto block = std::make_unique(AST_BLOCK, std::move(assign)); + auto block = std::make_unique(@$, AST_BLOCK, std::move(assign)); SET_AST_NODE_LOC(block.get(), @1, @3); - auto init = std::make_unique(AST_INITIAL, std::move(block)); + auto init = std::make_unique(@$, AST_INITIAL, std::move(block)); SET_AST_NODE_LOC(init.get(), @1, @3); extra->ast_stack.back()->children.push_back(std::move(init)); } else { - auto assign = std::make_unique(AST_ASSIGN, std::move(wire), std::move($3)); + auto assign = std::make_unique(@$, AST_ASSIGN, std::move(wire), std::move($3)); SET_AST_NODE_LOC(assign.get(), @1, @3); extra->ast_stack.back()->children.push_back(std::move(assign)); } @@ -2152,7 +2146,7 @@ assign_expr_list: assign_expr: lvalue TOK_EQ expr { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSIGN, std::move($1), std::move($3))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSIGN, std::move($1), std::move($3))); SET_AST_NODE_LOC(node, @$, @$); }; @@ -2181,12 +2175,12 @@ typedef_decl: typedef_base_type: hierarchical_type_id { - $$ = std::make_unique(AST_WIRE); + $$ = std::make_unique(@$, AST_WIRE); $$->is_logic = true; extra->addWiretypeNode($1.get(), $$.get()); } | integer_vector_type opt_signedness_default_unsigned { - $$ = std::make_unique(AST_WIRE); + $$ = std::make_unique(@$, AST_WIRE); if ($1 == token::TOK_REG) { $$->is_reg = true; } else { @@ -2195,7 +2189,7 @@ typedef_base_type: $$->is_signed = $2; } | integer_atom_type opt_signedness_default_signed { - $$ = std::make_unique(AST_WIRE); + $$ = std::make_unique(@$, AST_WIRE); $$->is_logic = true; $$->is_signed = $2; $$->range_left = $1 - 1; @@ -2209,15 +2203,15 @@ enum_struct_type: cell_stmt: attr TOK_ID { - extra->astbuf1 = std::make_unique(AST_CELL); + extra->astbuf1 = std::make_unique(@$, AST_CELL); append_attr(extra->astbuf1.get(), $1); - extra->astbuf1->children.push_back(std::make_unique(AST_CELLTYPE)); + extra->astbuf1->children.push_back(std::make_unique(@$, AST_CELLTYPE)); extra->astbuf1->children[0]->str = *$2; } cell_parameter_list_opt cell_list TOK_SEMICOL { (void)extra->astbuf1.reset(); } | attr tok_prim_wrapper delay { - extra->astbuf1 = std::make_unique(AST_PRIMITIVE); + extra->astbuf1 = std::make_unique(@$, AST_PRIMITIVE); extra->astbuf1->str = *$2; append_attr(extra->astbuf1.get(), $1); } prim_list TOK_SEMICOL { @@ -2260,7 +2254,7 @@ single_cell_arraylist: extra->astbuf2->str = *$1; // TODO optimize again extra->cell_hack = extra->astbuf2.get(); - extra->ast_stack.back()->children.push_back(std::make_unique(AST_CELLARRAY, std::move($2), std::move(extra->astbuf2))); + extra->ast_stack.back()->children.push_back(std::make_unique(@$, AST_CELLARRAY, std::move($2), std::move(extra->astbuf2))); } TOK_LPAREN cell_port_list TOK_RPAREN{ log_assert(extra->cell_hack); SET_AST_NODE_LOC(extra->cell_hack, @1, @$); @@ -2298,7 +2292,7 @@ cell_parameter_list: cell_parameter: %empty | expr { - auto node = std::make_unique(AST_PARASET); + auto node = std::make_unique(@$, AST_PARASET); node->children.push_back(std::move($1)); extra->astbuf1->children.push_back(std::move(node)); } | @@ -2306,7 +2300,7 @@ cell_parameter: // just ignore empty parameters } | TOK_DOT TOK_ID TOK_LPAREN expr TOK_RPAREN { - auto node = std::make_unique(AST_PARASET); + auto node = std::make_unique(@$, AST_PARASET); node->str = *$2; node->children.push_back(std::move($4)); extra->astbuf1->children.push_back(std::move(node)); @@ -2343,33 +2337,33 @@ cell_port_list_rules: cell_port: attr { - auto node = std::make_unique(AST_ARGUMENT); + auto node = std::make_unique(@$, AST_ARGUMENT); extra->cell_hack->children.push_back(std::move(node)); free_attr($1); } | attr expr { - auto node = std::make_unique(AST_ARGUMENT); + auto node = std::make_unique(@$, AST_ARGUMENT); node->children.push_back(std::move($2)); extra->cell_hack->children.push_back(std::move(node)); free_attr($1); } | attr TOK_DOT TOK_ID TOK_LPAREN expr TOK_RPAREN { - auto node = std::make_unique(AST_ARGUMENT); + auto node = std::make_unique(@$, AST_ARGUMENT); node->str = *$3; node->children.push_back(std::move($5)); extra->cell_hack->children.push_back(std::move(node)); free_attr($1); } | attr TOK_DOT TOK_ID TOK_LPAREN TOK_RPAREN { - auto node = std::make_unique(AST_ARGUMENT); + auto node = std::make_unique(@$, AST_ARGUMENT); node->str = *$3; extra->cell_hack->children.push_back(std::move(node)); free_attr($1); } | attr TOK_DOT TOK_ID { - auto node = std::make_unique(AST_ARGUMENT); + auto node = std::make_unique(@$, AST_ARGUMENT); node->str = *$3; - node->children.push_back(std::make_unique(AST_IDENTIFIER)); + node->children.push_back(std::make_unique(@$, AST_IDENTIFIER)); node->children.back()->str = *$3; extra->cell_hack->children.push_back(std::move(node)); free_attr($1); @@ -2377,7 +2371,7 @@ cell_port: attr TOK_WILDCARD_CONNECT { if (!mode->sv) err_at_loc(@2, "Wildcard port connections are only supported in SystemVerilog mode."); - extra->cell_hack->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(1, false); + extra->cell_hack->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(@2, 1, false); free_attr($1); }; @@ -2399,12 +2393,12 @@ always_or_always_ff: always_stmt: attr always_or_always_ff { - AstNode* node = extra->pushChild(std::make_unique(AST_ALWAYS)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_ALWAYS)); append_attr(node, $1); if ($2) - node->attributes[ID::always_ff] = AstNode::mkconst_int(1, false); + node->attributes[ID::always_ff] = AstNode::mkconst_int(@2, 1, false); } always_cond { - (void)extra->pushChild(std::make_unique(AST_BLOCK)); + (void)extra->pushChild(std::make_unique(@$, AST_BLOCK)); } behavioral_stmt { SET_AST_NODE_LOC(extra->ast_stack.back(), @6, @6); extra->ast_stack.pop_back(); @@ -2415,21 +2409,21 @@ always_stmt: SET_RULE_LOC(@$, @2, @$); } | attr always_comb_or_latch { - AstNode* node = extra->pushChild(std::make_unique(AST_ALWAYS)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_ALWAYS)); append_attr(node, $1); if ($2) - node->attributes[ID::always_latch] = AstNode::mkconst_int(1, false); + node->attributes[ID::always_latch] = AstNode::mkconst_int(@2, 1, false); else - node->attributes[ID::always_comb] = AstNode::mkconst_int(1, false); - (void)extra->pushChild(std::make_unique(AST_BLOCK)); + node->attributes[ID::always_comb] = AstNode::mkconst_int(@2, 1, false); + (void)extra->pushChild(std::make_unique(@$, AST_BLOCK)); } behavioral_stmt { extra->ast_stack.pop_back(); extra->ast_stack.pop_back(); } | attr TOK_INITIAL { - AstNode* node = extra->pushChild(std::make_unique(AST_INITIAL)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_INITIAL)); append_attr(node, $1); - (void)extra->pushChild(std::make_unique(AST_BLOCK)); + (void)extra->pushChild(std::make_unique(@$, AST_BLOCK)); } behavioral_stmt { extra->ast_stack.pop_back(); extra->ast_stack.pop_back(); @@ -2450,19 +2444,19 @@ always_events: always_event: TOK_POSEDGE expr { - auto node = std::make_unique(AST_POSEDGE); + auto node = std::make_unique(@$, AST_POSEDGE); SET_AST_NODE_LOC(node.get(), @1, @1); node->children.push_back(std::move($2)); extra->ast_stack.back()->children.push_back(std::move(node)); } | TOK_NEGEDGE expr { - auto node = std::make_unique(AST_NEGEDGE); + auto node = std::make_unique(@$, AST_NEGEDGE); SET_AST_NODE_LOC(node.get(), @1, @1); node->children.push_back(std::move($2)); extra->ast_stack.back()->children.push_back(std::move(node)); } | expr { - auto node = std::make_unique(AST_EDGE); + auto node = std::make_unique(@$, AST_EDGE); node->children.push_back(std::move($1)); extra->ast_stack.back()->children.push_back(std::move(node)); }; @@ -2496,7 +2490,7 @@ opt_property: modport_stmt: TOK_MODPORT TOK_ID { - AstNode* modport = extra->pushChild(std::make_unique(AST_MODPORT)); + AstNode* modport = extra->pushChild(std::make_unique(@$, AST_MODPORT)); modport->str = *$2; } modport_args_opt { @@ -2516,7 +2510,7 @@ modport_arg: modport_member: TOK_ID { - AstNode* modport_member = extra->saveChild(std::make_unique(AST_MODPORTMEMBER)); + AstNode* modport_member = extra->saveChild(std::make_unique(@$, AST_MODPORTMEMBER)); modport_member->str = *$1; modport_member->is_input = extra->current_modport_input; modport_member->is_output = extra->current_modport_output; @@ -2531,7 +2525,7 @@ assert: if (mode->noassert) { } else { - AstNode* node = extra->saveChild(std::make_unique(mode->assume_asserts ? AST_ASSUME : AST_ASSERT, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assume_asserts ? AST_ASSUME : AST_ASSERT, std::move($5))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; @@ -2540,7 +2534,7 @@ assert: opt_sva_label TOK_ASSUME opt_property TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { if (mode->noassume) { } else { - AstNode* node = extra->saveChild(std::make_unique(mode->assert_assumes ? AST_ASSERT : AST_ASSUME, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assert_assumes ? AST_ASSERT : AST_ASSUME, std::move($5))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; @@ -2549,7 +2543,7 @@ assert: opt_sva_label TOK_ASSERT opt_property TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { if (mode->noassert) { } else { - AstNode* node = extra->saveChild(std::make_unique(mode->assume_asserts ? AST_FAIR : AST_LIVE, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assume_asserts ? AST_FAIR : AST_LIVE, std::move($6))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; @@ -2558,28 +2552,28 @@ assert: opt_sva_label TOK_ASSUME opt_property TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { if (mode->noassume) { } else { - AstNode* node = extra->saveChild(std::make_unique(mode->assert_assumes ? AST_LIVE : AST_FAIR, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assert_assumes ? AST_LIVE : AST_FAIR, std::move($6))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; } } | opt_sva_label TOK_COVER opt_property TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_COVER, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_COVER, std::move($5))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) { node->str = *$1; } } | opt_sva_label TOK_COVER opt_property TOK_LPAREN TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_COVER, AstNode::mkconst_int(1, false))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_COVER, AstNode::mkconst_int(@$, 1, false))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @5); if ($1 != nullptr) { node->str = *$1; } } | opt_sva_label TOK_COVER TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_COVER, AstNode::mkconst_int(1, false))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_COVER, AstNode::mkconst_int(@$, 1, false))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @2); if ($1 != nullptr) { node->str = *$1; @@ -2588,57 +2582,57 @@ assert: opt_sva_label TOK_RESTRICT opt_property TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { if (mode->norestrict) { } else { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSUME, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSUME, std::move($5))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; } if (!$3) - log_file_warning(current_filename, @$.begin.line, "SystemVerilog does not allow \"restrict\" without \"property\".\n"); + err_at_loc(@$, "SystemVerilog does not allow \"restrict\" without \"property\".\n"); } | opt_sva_label TOK_RESTRICT opt_property TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { if (mode->norestrict) { } else { - AstNode* node = extra->saveChild(std::make_unique(AST_FAIR, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_FAIR, std::move($6))); SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; } if (!$3) - log_file_warning(current_filename, @$.begin.line, "SystemVerilog does not allow \"restrict\" without \"property\".\n"); + err_at_loc(@$, "SystemVerilog does not allow \"restrict\" without \"property\".\n"); }; assert_property: opt_sva_label TOK_ASSERT TOK_PROPERTY TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(mode->assume_asserts ? AST_ASSUME : AST_ASSERT, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assume_asserts ? AST_ASSUME : AST_ASSERT, std::move($5))); SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; } } | opt_sva_label TOK_ASSUME TOK_PROPERTY TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSUME, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSUME, std::move($5))); SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; } } | opt_sva_label TOK_ASSERT TOK_PROPERTY TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(mode->assume_asserts ? AST_FAIR : AST_LIVE, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, mode->assume_asserts ? AST_FAIR : AST_LIVE, std::move($6))); SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; } } | opt_sva_label TOK_ASSUME TOK_PROPERTY TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_FAIR, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_FAIR, std::move($6))); SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; } } | opt_sva_label TOK_COVER TOK_PROPERTY TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { - AstNode* node = extra->saveChild(std::make_unique(AST_COVER, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_COVER, std::move($5))); SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; @@ -2647,7 +2641,7 @@ assert_property: opt_sva_label TOK_RESTRICT TOK_PROPERTY TOK_LPAREN expr TOK_RPAREN TOK_SEMICOL { if (mode->norestrict) { } else { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSUME, std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSUME, std::move($5))); SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; @@ -2657,7 +2651,7 @@ assert_property: opt_sva_label TOK_RESTRICT TOK_PROPERTY TOK_LPAREN TOK_EVENTUALLY expr TOK_RPAREN TOK_SEMICOL { if (mode->norestrict) { } else { - AstNode* node = extra->saveChild(std::make_unique(AST_FAIR, std::move($6))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_FAIR, std::move($6))); SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) { extra->ast_stack.back()->children.back()->str = *$1; @@ -2667,23 +2661,23 @@ assert_property: simple_behavioral_stmt: attr lvalue TOK_EQ delay expr { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSIGN_EQ, std::move($2), std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSIGN_EQ, std::move($2), std::move($5))); SET_AST_NODE_LOC(node, @2, @5); append_attr(node, $1); } | attr lvalue attr inc_or_dec_op { - extra->addIncOrDecStmt($1, std::move($2), $3, $4, @1, @4); + extra->addIncOrDecStmt($1, std::move($2), $3, $4, location_range(@1, @4)); } | attr inc_or_dec_op attr lvalue { - extra->addIncOrDecStmt($1, std::move($4), $3, $2, @1, @4); + extra->addIncOrDecStmt($1, std::move($4), $3, $2, location_range(@1, @4)); } | attr lvalue OP_LE delay expr { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSIGN_LE, std::move($2), std::move($5))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSIGN_LE, std::move($2), std::move($5))); SET_AST_NODE_LOC(node, @2, @5); append_attr(node, $1); } | attr lvalue asgn_binop delay expr { - (void)extra->addAsgnBinopStmt($1, std::move($2), $3, std::move($5), @2, @5); + (void)extra->addAsgnBinopStmt($1, std::move($2), $3, std::move($5)); }; asgn_binop: @@ -2708,9 +2702,9 @@ inc_or_dec_op: for_initialization: TOK_ID TOK_EQ expr { - auto ident = std::make_unique(AST_IDENTIFIER); + auto ident = std::make_unique(@$, AST_IDENTIFIER); ident->str = *$1; - auto node = std::make_unique(AST_ASSIGN_EQ, std::move(ident), std::move($3)); + auto node = std::make_unique(@$, AST_ASSIGN_EQ, std::move(ident), std::move($3)); SET_AST_NODE_LOC(node.get(), @1, @3); extra->ast_stack.back()->children.push_back(std::move(node)); } | @@ -2729,7 +2723,7 @@ for_initialization: if (range != nullptr) wire->children.push_back(std::move(range)); - auto ident = std::make_unique(AST_IDENTIFIER); + auto ident = std::make_unique(@$, AST_IDENTIFIER); ident->str = *$3; wire->str = *$3; @@ -2739,13 +2733,13 @@ for_initialization: // loop variable initialization SET_AST_NODE_LOC(ident.get(), @3, @3); - auto asgn = std::make_unique(AST_ASSIGN_EQ, std::move(ident), std::move($5)); + auto asgn = std::make_unique(@$, AST_ASSIGN_EQ, std::move(ident), std::move($5)); SET_AST_NODE_LOC(asgn.get(), @3, @5); loop->children.push_back(std::move(asgn)); // inject a wrapping block to declare the loop variable and // contain the current loop - auto wrapper = std::make_unique(AST_BLOCK); + auto wrapper = std::make_unique(@$, AST_BLOCK); wrapper->str = "$fordecl_block$" + std::to_string(autoidx++); wrapper->children.push_back(std::move(wire)); wrapper->children.push_back(std::move(loop)); @@ -2761,7 +2755,7 @@ behavioral_stmt: free_attr($1); } | attr hierarchical_id { - AstNode* node = extra->pushChild(std::make_unique(AST_TCALL)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_TCALL)); node->str = *$2; append_attr(node, $1); } opt_arg_list TOK_SEMICOL{ @@ -2769,7 +2763,7 @@ behavioral_stmt: extra->ast_stack.pop_back(); } | attr TOK_MSG_TASKS { - AstNode* node = extra->pushChild(std::make_unique(AST_TCALL)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_TCALL)); node->str = *$2; append_attr(node, $1); } opt_arg_list TOK_SEMICOL{ @@ -2779,7 +2773,7 @@ behavioral_stmt: attr TOK_BEGIN { extra->enterTypeScope(); } opt_label { - AstNode* node = extra->pushChild(std::make_unique(AST_BLOCK)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_BLOCK)); append_attr(node, $1); if ($4 != nullptr) node->str = *$4; @@ -2800,12 +2794,12 @@ behavioral_stmt: extra->ast_stack.pop_back(); } | attr TOK_FOR TOK_LPAREN { - AstNode* node = extra->pushChild(std::make_unique(AST_FOR)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_FOR)); append_attr(node, $1); } for_initialization TOK_SEMICOL expr { extra->ast_stack.back()->children.push_back(std::move($7)); } TOK_SEMICOL simple_behavioral_stmt TOK_RPAREN { - AstNode* block = extra->pushChild(std::make_unique(AST_BLOCK)); + AstNode* block = extra->pushChild(std::make_unique(@$, AST_BLOCK)); block->str = "$for_loop$" + std::to_string(autoidx++); } behavioral_stmt { SET_AST_NODE_LOC(extra->ast_stack.back(), @13, @13); @@ -2814,9 +2808,9 @@ behavioral_stmt: extra->ast_stack.pop_back(); } | attr TOK_WHILE TOK_LPAREN expr TOK_RPAREN { - AstNode* node = extra->pushChild(std::make_unique(AST_WHILE)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_WHILE)); append_attr(node, $1); - auto block_owned = std::make_unique(AST_BLOCK); + auto block_owned = std::make_unique(@$, AST_BLOCK); auto* block = block_owned.get(); extra->ast_stack.back()->children.push_back(std::move($4)); extra->ast_stack.back()->children.push_back(std::move(block_owned)); @@ -2827,9 +2821,9 @@ behavioral_stmt: extra->ast_stack.pop_back(); } | attr TOK_REPEAT TOK_LPAREN expr TOK_RPAREN { - AstNode* node = extra->pushChild(std::make_unique(AST_REPEAT)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_REPEAT)); append_attr(node, $1); - auto block_owned = std::make_unique(AST_BLOCK); + auto block_owned = std::make_unique(@$, AST_BLOCK); auto* block = block_owned.get(); extra->ast_stack.back()->children.push_back(std::move($4)); extra->ast_stack.back()->children.push_back(std::move(block_owned)); @@ -2856,22 +2850,22 @@ behavioral_stmt: // we have to undangle it from the stack patch_block_on_stack = true; } else if (outer->get_bool_attribute(ID::full_case)) - (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false); } - auto expr = std::make_unique(AST_REDUCE_BOOL, std::move($4)); + auto expr = std::make_unique(@$, AST_REDUCE_BOOL, std::move($4)); if (!node) { // not parallel "else if": begin new construction - node_owned = std::make_unique(AST_CASE); + node_owned = std::make_unique(@$, AST_CASE); node = node_owned.get(); append_attr(node, $1); - node->children.push_back(node->get_bool_attribute(ID::parallel_case) ? AstNode::mkconst_int(1, false, 1) : expr->clone()); + node->children.push_back(node->get_bool_attribute(ID::parallel_case) ? AstNode::mkconst_int(@$, 1, false, 1) : expr->clone()); extra->ast_stack.back()->children.push_back(std::move(node_owned)); } else { free_attr($1); } - auto block_owned = std::make_unique(AST_BLOCK); + auto block_owned = std::make_unique(@$, AST_BLOCK); auto* block = block_owned.get(); - auto cond_owned = std::make_unique(AST_COND, node->get_bool_attribute(ID::parallel_case) ? std::move(expr) : AstNode::mkconst_int(1, false, 1), std::move(block_owned)); + auto cond_owned = std::make_unique(@$, AST_COND, node->get_bool_attribute(ID::parallel_case) ? std::move(expr) : AstNode::mkconst_int(@$, 1, false, 1), std::move(block_owned)); SET_AST_NODE_LOC(cond_owned.get(), @4, @4); node->children.push_back(std::move(cond_owned)); // Double it and give it to the next person @@ -2887,7 +2881,7 @@ behavioral_stmt: extra->ast_stack.pop_back(); } | case_attr case_type TOK_LPAREN expr TOK_RPAREN { - AstNode* node = extra->pushChild(std::make_unique(AST_CASE, std::move($4))); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_CASE, std::move($4))); append_attr(node, $1); SET_AST_NODE_LOC(extra->ast_stack.back(), @4, @4); } opt_synopsys_attr case_body TOK_ENDCASE { @@ -2904,22 +2898,22 @@ if_attr: AstNode *context = extra->ast_stack.back(); if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if)) err_at_loc(@2, "unique0 keyword cannot be used for 'else if' branch."); - (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; } | attr TOK_PRIORITY { AstNode *context = extra->ast_stack.back(); if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if)) err_at_loc(@2, "priority keyword cannot be used for 'else if' branch."); - (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; } | attr TOK_UNIQUE { AstNode *context = extra->ast_stack.back(); if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if)) err_at_loc(@2, "unique keyword cannot be used for 'else if' branch."); - (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); - (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false); + (*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; }; @@ -2928,16 +2922,16 @@ case_attr: $$ = $1; } | attr TOK_UNIQUE0 { - (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; } | attr TOK_PRIORITY { - (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; } | attr TOK_UNIQUE { - (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); - (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false); + (*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false); $$ = $1; }; @@ -2955,11 +2949,11 @@ case_type: opt_synopsys_attr: opt_synopsys_attr TOK_SYNOPSYS_FULL_CASE { if (extra->ast_stack.back()->attributes.count(ID::full_case) == 0) - extra->ast_stack.back()->attributes[ID::full_case] = AstNode::mkconst_int(1, false); + extra->ast_stack.back()->attributes[ID::full_case] = AstNode::mkconst_int(@$, 1, false); } | opt_synopsys_attr TOK_SYNOPSYS_PARALLEL_CASE { if (extra->ast_stack.back()->attributes.count(ID::parallel_case) == 0) - extra->ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false); + extra->ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false); } | %empty; @@ -2970,12 +2964,12 @@ behavioral_stmt_list: optional_else: TOK_ELSE { extra->ast_stack.pop_back(); - auto block_owned = std::make_unique(AST_BLOCK); + auto block_owned = std::make_unique(@$, AST_BLOCK); auto* block = block_owned.get(); - block->attributes[ID::promoted_if] = AstNode::mkconst_int(1, false); + block->attributes[ID::promoted_if] = AstNode::mkconst_int(@$, 1, false); AstNode* cond = extra->saveChild( - std::make_unique(AST_COND, - std::make_unique(AST_DEFAULT), + std::make_unique(@$, AST_COND, + std::make_unique(@$, AST_DEFAULT), std::move(block_owned))); extra->ast_stack.push_back(block); SET_AST_NODE_LOC(cond, @1, @1); @@ -2991,10 +2985,11 @@ case_body: case_item: { (void)extra->pushChild(std::make_unique( + @$, extra->case_type_stack.size() && extra->case_type_stack.back() == 'x' ? AST_CONDX : extra->case_type_stack.size() && extra->case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND)); } case_select { - (void)extra->pushChild(std::make_unique(AST_BLOCK)); + (void)extra->pushChild(std::make_unique(@$, AST_BLOCK)); extra->case_type_stack.push_back(0); } behavioral_stmt { extra->case_type_stack.pop_back(); @@ -3010,6 +3005,7 @@ gen_case_body: gen_case_item: { (void)extra->pushChild(std::make_unique( + @$, extra->case_type_stack.size() && extra->case_type_stack.back() == 'x' ? AST_CONDX : extra->case_type_stack.size() && extra->case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND)); } case_select { @@ -3026,11 +3022,11 @@ case_select: case_expr_list: TOK_DEFAULT { - AstNode* node = extra->saveChild(std::make_unique(AST_DEFAULT)); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_DEFAULT)); SET_AST_NODE_LOC(node, @1, @1); } | TOK_SVA_LABEL { - AstNode* node = extra->pushChild(std::make_unique(AST_IDENTIFIER)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_IDENTIFIER)); SET_AST_NODE_LOC(node, @1, @1); } | expr { @@ -3042,12 +3038,12 @@ case_expr_list: rvalue: hierarchical_id TOK_LBRA expr TOK_RBRA TOK_DOT rvalue { - $$ = std::make_unique(AST_PREFIX, std::move($3), std::move($6)); + $$ = std::make_unique(@$, AST_PREFIX, std::move($3), std::move($6)); $$->str = *$1; SET_AST_NODE_LOC($$.get(), @1, @6); } | hierarchical_id range { - $$ = std::make_unique(AST_IDENTIFIER, std::move($2)); + $$ = std::make_unique(@$, AST_IDENTIFIER, std::move($2)); $$->str = *$1; SET_AST_NODE_LOC($$.get(), @1, @1); if ($2 == nullptr && ($$->str == "\\$initstate" || @@ -3056,7 +3052,7 @@ rvalue: $$->type = AST_FCALL; } | hierarchical_id non_opt_multirange { - $$ = std::make_unique(AST_IDENTIFIER, std::move($2)); + $$ = std::make_unique(@$, AST_IDENTIFIER, std::move($2)); $$->str = *$1; SET_AST_NODE_LOC($$.get(), @1, @1); }; @@ -3071,7 +3067,7 @@ lvalue: lvalue_concat_list: expr { - $$ = std::make_unique(AST_CONCAT); + $$ = std::make_unique(@$, AST_CONCAT); $$->children.push_back(std::move($1)); } | expr TOK_COMMA lvalue_concat_list { @@ -3109,7 +3105,7 @@ gen_stmt_or_module_body_stmt: genvar_identifier: TOK_ID { - $$ = std::make_unique(AST_IDENTIFIER); + $$ = std::make_unique(@$, AST_IDENTIFIER); $$->str = *$1; }; @@ -3120,7 +3116,7 @@ genvar_initialization: TOK_GENVAR genvar_identifier TOK_EQ expr { if (!mode->sv) err_at_loc(@3, "Generate for loop inline variable declaration is only supported in SystemVerilog mode!"); - AstNode* node = extra->saveChild(std::make_unique(AST_GENVAR)); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_GENVAR)); node->is_reg = true; node->is_signed = true; node->range_left = 31; @@ -3128,18 +3124,18 @@ genvar_initialization: node->str = $2->str; node->children.push_back(checkRange(node, nullptr)); SET_AST_NODE_LOC(node, @1, @4); - node = extra->saveChild(std::make_unique(AST_ASSIGN_EQ, std::move($2), std::move($4))); + node = extra->saveChild(std::make_unique(@$, AST_ASSIGN_EQ, std::move($2), std::move($4))); SET_AST_NODE_LOC(node, @1, @4); } | genvar_identifier TOK_EQ expr { - AstNode* node = extra->saveChild(std::make_unique(AST_ASSIGN_EQ, std::move($1), std::move($3))); + AstNode* node = extra->saveChild(std::make_unique(@$, AST_ASSIGN_EQ, std::move($1), std::move($3))); SET_AST_NODE_LOC(node, @1, @3); }; // this production creates the obligatory if-else shift/reduce conflict gen_stmt: TOK_FOR TOK_LPAREN { - (void)extra->pushChild(std::make_unique(AST_GENFOR)); + (void)extra->pushChild(std::make_unique(@$, AST_GENFOR)); } genvar_initialization TOK_SEMICOL expr { extra->ast_stack.back()->children.push_back(std::move($6)); } TOK_SEMICOL simple_behavioral_stmt TOK_RPAREN gen_stmt_block { @@ -3148,21 +3144,21 @@ gen_stmt: extra->ast_stack.pop_back(); } | TOK_IF TOK_LPAREN expr TOK_RPAREN { - (void)extra->pushChild(std::make_unique(AST_GENIF)); + (void)extra->pushChild(std::make_unique(@$, AST_GENIF)); extra->ast_stack.back()->children.push_back(std::move($3)); } gen_stmt_block opt_gen_else { SET_AST_NODE_LOC(extra->ast_stack.back(), @1, @7); extra->ast_stack.pop_back(); } | case_type TOK_LPAREN expr TOK_RPAREN { - (void)extra->pushChild(std::make_unique(AST_GENCASE, std::move($3))); + (void)extra->pushChild(std::make_unique(@$, AST_GENCASE, std::move($3))); } gen_case_body TOK_ENDCASE { extra->case_type_stack.pop_back(); SET_AST_NODE_LOC(extra->ast_stack.back(), @1, @7); extra->ast_stack.pop_back(); } | TOK_MSG_TASKS { - AstNode* node = extra->pushChild(std::make_unique(AST_TECALL)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_TECALL)); node->str = *$1; } opt_arg_list TOK_SEMICOL{ SET_AST_NODE_LOC(extra->ast_stack.back(), @1, @3); @@ -3173,7 +3169,7 @@ gen_block: TOK_BEGIN { extra->enterTypeScope(); } opt_label { - AstNode* node = extra->pushChild(std::make_unique(AST_GENBLOCK)); + AstNode* node = extra->pushChild(std::make_unique(@$, AST_GENBLOCK)); node->str = $3 ? *$3 : std::string(); } module_gen_body TOK_END opt_label { extra->exitTypeScope(); @@ -3185,7 +3181,7 @@ gen_block: // result is wrapped in a genblock only if necessary gen_stmt_block: { - (void)extra->pushChild(std::make_unique(AST_GENBLOCK)); + (void)extra->pushChild(std::make_unique(@$, AST_GENBLOCK)); } gen_stmt_or_module_body_stmt { SET_AST_NODE_LOC(extra->ast_stack.back(), @2, @2); extra->ast_stack.pop_back(); @@ -3199,7 +3195,7 @@ expr: $$ = std::move($1); } | basic_expr TOK_QUE attr expr TOK_COL expr { - $$ = std::make_unique(AST_TERNARY); + $$ = std::make_unique(@$, AST_TERNARY); $$->children.push_back(std::move($1)); $$->children.push_back(std::move($4)); $$->children.push_back(std::move($6)); @@ -3207,12 +3203,12 @@ expr: append_attr($$.get(), $3); } | inc_or_dec_op attr rvalue { - $$ = extra->addIncOrDecExpr(std::move($3), $2, $1, @1, @3, false, mode->sv); + $$ = extra->addIncOrDecExpr(std::move($3), $2, $1, location_range(@1, @3), false, mode->sv); } | // TODO: Attributes are allowed in the middle here, but they create some // non-trivial conflicts that don't seem worth solving for now. rvalue inc_or_dec_op { - $$ = extra->addIncOrDecExpr(std::move($1), nullptr, $2, @1, @2, true, mode->sv); + $$ = extra->addIncOrDecExpr(std::move($1), nullptr, $2, location_range(@1, @2), true, mode->sv); }; basic_expr: @@ -3226,12 +3222,12 @@ basic_expr: auto val = p.const2ast(*$4, extra->case_type_stack.size() == 0 ? 0 : extra->case_type_stack.back(), !mode->lib); if (val == nullptr) log_error("Value conversion failed: `%s'\n", $4->c_str()); - $$ = std::make_unique(AST_TO_BITS, std::move($2), std::move(val)); + $$ = std::make_unique(@$, AST_TO_BITS, std::move($2), std::move(val)); } | hierarchical_id integral_number { if ($2->compare(0, 1, "'") != 0) err_at_loc(@2, "Cast operation must be applied on sized constants, e.g. \'d0, while %s is not a sized constant.", $2->c_str()); - auto bits = std::make_unique(AST_IDENTIFIER); + auto bits = std::make_unique(@$, AST_IDENTIFIER); bits->str = *$1; SET_AST_NODE_LOC(bits.get(), @1, @1); auto p = make_ConstParser_here(@2); @@ -3239,7 +3235,7 @@ basic_expr: SET_AST_NODE_LOC(val.get(), @2, @2); if (val == nullptr) log_error("Value conversion failed: `%s'\n", $2->c_str()); - $$ = std::make_unique(AST_TO_BITS, std::move(bits), std::move(val)); + $$ = std::make_unique(@$, AST_TO_BITS, std::move(bits), std::move(val)); } | integral_number { auto p = make_ConstParser_here(@1); @@ -3249,7 +3245,7 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); } | TOK_REALVAL { - $$ = std::make_unique(AST_REALVALUE); + $$ = std::make_unique(@$, AST_REALVALUE); char *p = (char*)malloc(GetSize(*$1) + 1), *q; for (int i = 0, j = 0; j < GetSize(*$1); j++) if ((*$1)[j] != '_') @@ -3260,12 +3256,12 @@ basic_expr: free(p); } | TOK_STRING { - $$ = AstNode::mkconst_str(*$1); + $$ = AstNode::mkconst_str(@1, *$1); SET_AST_NODE_LOC($$.get(), @1, @1); } | hierarchical_id attr { // super sketchy! Orphaned pointer in non-owning extra->ast_stack - AstNode *node = new AstNode(AST_FCALL); + AstNode *node = new AstNode(@1, AST_FCALL); node->str = *$1; extra->ast_stack.push_back(node); SET_AST_NODE_LOC(node, @1, @1); @@ -3275,11 +3271,11 @@ basic_expr: extra->ast_stack.pop_back(); } | TOK_TO_SIGNED attr TOK_LPAREN expr TOK_RPAREN { - $$ = std::make_unique(AST_TO_SIGNED, std::move($4)); + $$ = std::make_unique(@$, AST_TO_SIGNED, std::move($4)); append_attr($$.get(), $2); } | TOK_TO_UNSIGNED attr TOK_LPAREN expr TOK_RPAREN { - $$ = std::make_unique(AST_TO_UNSIGNED, std::move($4)); + $$ = std::make_unique(@$, AST_TO_UNSIGNED, std::move($4)); append_attr($$.get(), $2); } | TOK_LPAREN expr TOK_RPAREN { @@ -3292,230 +3288,230 @@ basic_expr: $$ = std::move($2); } | TOK_LCURL expr TOK_LCURL concat_list TOK_RCURL TOK_RCURL { - $$ = std::make_unique(AST_REPLICATE, std::move($2), std::move($4)); + $$ = std::make_unique(@$, AST_REPLICATE, std::move($2), std::move($4)); } | TOK_TILDE attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_BIT_NOT, std::move($3)); + $$ = std::make_unique(@$, AST_BIT_NOT, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | basic_expr TOK_AMP attr basic_expr { - $$ = std::make_unique(AST_BIT_AND, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_BIT_AND, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_NAND attr basic_expr { - $$ = std::make_unique(AST_BIT_NOT, std::make_unique(AST_BIT_AND, std::move($1), std::move($4))); + $$ = std::make_unique(@$, AST_BIT_NOT, std::make_unique(@$, AST_BIT_AND, std::move($1), std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_PIPE attr basic_expr { - $$ = std::make_unique(AST_BIT_OR, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_BIT_OR, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_NOR attr basic_expr { - $$ = std::make_unique(AST_BIT_NOT, std::make_unique(AST_BIT_OR, std::move($1), std::move($4))); + $$ = std::make_unique(@$, AST_BIT_NOT, std::make_unique(@$, AST_BIT_OR, std::move($1), std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_CARET attr basic_expr { - $$ = std::make_unique(AST_BIT_XOR, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_BIT_XOR, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_XNOR attr basic_expr { - $$ = std::make_unique(AST_BIT_XNOR, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_BIT_XNOR, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | TOK_AMP attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_AND, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_AND, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | OP_NAND attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_AND, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_AND, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); - $$ = std::make_unique(AST_LOGIC_NOT, std::move($$)); + $$ = std::make_unique(@$, AST_LOGIC_NOT, std::move($$)); } | TOK_PIPE attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_OR, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_OR, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), std::move($2)); } | OP_NOR attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_OR, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_OR, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); - $$ = std::make_unique(AST_LOGIC_NOT, std::move($$)); + $$ = std::make_unique(@$, AST_LOGIC_NOT, std::move($$)); SET_AST_NODE_LOC($$.get(), @1, @3); } | TOK_CARET attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_XOR, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_XOR, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | OP_XNOR attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_REDUCE_XNOR, std::move($3)); + $$ = std::make_unique(@$, AST_REDUCE_XNOR, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | basic_expr OP_SHL attr basic_expr { - $$ = std::make_unique(AST_SHIFT_LEFT, std::move($1), std::make_unique(AST_TO_UNSIGNED, std::move($4))); + $$ = std::make_unique(@$, AST_SHIFT_LEFT, std::move($1), std::make_unique(@$, AST_TO_UNSIGNED, std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_SHR attr basic_expr { - $$ = std::make_unique(AST_SHIFT_RIGHT, std::move($1), std::make_unique(AST_TO_UNSIGNED, std::move($4))); + $$ = std::make_unique(@$, AST_SHIFT_RIGHT, std::move($1), std::make_unique(@$, AST_TO_UNSIGNED, std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_SSHL attr basic_expr { - $$ = std::make_unique(AST_SHIFT_SLEFT, std::move($1), std::make_unique(AST_TO_UNSIGNED, std::move($4))); + $$ = std::make_unique(@$, AST_SHIFT_SLEFT, std::move($1), std::make_unique(@$, AST_TO_UNSIGNED, std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_SSHR attr basic_expr { - $$ = std::make_unique(AST_SHIFT_SRIGHT, std::move($1), std::make_unique(AST_TO_UNSIGNED, std::move($4))); + $$ = std::make_unique(@$, AST_SHIFT_SRIGHT, std::move($1), std::make_unique(@$, AST_TO_UNSIGNED, std::move($4))); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_LT attr basic_expr { - $$ = std::make_unique(AST_LT, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_LT, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_LE attr basic_expr { - $$ = std::make_unique(AST_LE, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_LE, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_EQ attr basic_expr { - $$ = std::make_unique(AST_EQ, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_EQ, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_NE attr basic_expr { - $$ = std::make_unique(AST_NE, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_NE, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_EQX attr basic_expr { - $$ = std::make_unique(AST_EQX, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_EQX, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_NEX attr basic_expr { - $$ = std::make_unique(AST_NEX, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_NEX, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_GE attr basic_expr { - $$ = std::make_unique(AST_GE, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_GE, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_GT attr basic_expr { - $$ = std::make_unique(AST_GT, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_GT, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_PLUS attr basic_expr { - $$ = std::make_unique(AST_ADD, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_ADD, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_MINUS attr basic_expr { - $$ = std::make_unique(AST_SUB, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_SUB, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_ASTER attr basic_expr { - $$ = std::make_unique(AST_MUL, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_MUL, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_SLASH attr basic_expr { - $$ = std::make_unique(AST_DIV, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_DIV, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr TOK_PERC attr basic_expr { - $$ = std::make_unique(AST_MOD, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_MOD, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_POW attr basic_expr { - $$ = std::make_unique(AST_POW, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_POW, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | TOK_PLUS attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_POS, std::move($3)); + $$ = std::make_unique(@$, AST_POS, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | TOK_MINUS attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_NEG, std::move($3)); + $$ = std::make_unique(@$, AST_NEG, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | basic_expr OP_LAND attr basic_expr { - $$ = std::make_unique(AST_LOGIC_AND, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_LOGIC_AND, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | basic_expr OP_LOR attr basic_expr { - $$ = std::make_unique(AST_LOGIC_OR, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_LOGIC_OR, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); append_attr($$.get(), $3); } | TOK_EXCL attr basic_expr %prec UNARY_OPS { - $$ = std::make_unique(AST_LOGIC_NOT, std::move($3)); + $$ = std::make_unique(@$, AST_LOGIC_NOT, std::move($3)); SET_AST_NODE_LOC($$.get(), @1, @3); append_attr($$.get(), $2); } | TOK_SIGNED OP_CAST TOK_LPAREN expr TOK_RPAREN { if (!mode->sv) err_at_loc(@2, "Static cast is only supported in SystemVerilog mode."); - $$ = std::make_unique(AST_TO_SIGNED, std::move($4)); + $$ = std::make_unique(@$, AST_TO_SIGNED, std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); } | TOK_UNSIGNED OP_CAST TOK_LPAREN expr TOK_RPAREN { if (!mode->sv) err_at_loc(@2, "Static cast is only supported in SystemVerilog mode."); - $$ = std::make_unique(AST_TO_UNSIGNED, std::move($4)); + $$ = std::make_unique(@$, AST_TO_UNSIGNED, std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); } | basic_expr OP_CAST TOK_LPAREN expr TOK_RPAREN { if (!mode->sv) err_at_loc(@2, "Static cast is only supported in SystemVerilog mode."); - $$ = std::make_unique(AST_CAST_SIZE, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_CAST_SIZE, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); } | typedef_base_type OP_CAST TOK_LPAREN expr TOK_RPAREN { if (!mode->sv) err_at_loc(@2, "Static cast is only supported in SystemVerilog mode."); - $$ = std::make_unique(AST_CAST_SIZE, std::move($1), std::move($4)); + $$ = std::make_unique(@$, AST_CAST_SIZE, std::move($1), std::move($4)); SET_AST_NODE_LOC($$.get(), @1, @4); } | TOK_LPAREN expr TOK_EQ expr TOK_RPAREN { extra->ensureAsgnExprAllowed(@3, mode->sv); $$ = $2->clone(); - auto node = std::make_unique(AST_ASSIGN_EQ, std::move($2), std::move($4)); + auto node = std::make_unique(@$, AST_ASSIGN_EQ, std::move($2), std::move($4)); SET_AST_NODE_LOC(node.get(), @2, @4); extra->ast_stack.back()->children.push_back(std::move(node)); } | TOK_LPAREN expr asgn_binop expr TOK_RPAREN { extra->ensureAsgnExprAllowed(@3, mode->sv); - $$ = extra->addAsgnBinopStmt(nullptr, std::move($2), $3, std::move($4), @2, @4)-> clone(); + $$ = extra->addAsgnBinopStmt(nullptr, std::move($2), $3, std::move($4))-> clone(); }; concat_list: expr { - $$ = std::make_unique(AST_CONCAT, std::move($1)); + $$ = std::make_unique(@$, AST_CONCAT, std::move($1)); } | expr TOK_COMMA concat_list { $$ = std::move($3); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d9e437ac5..d0355311d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -5704,7 +5704,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri { cover("kernel.rtlil.sigspec.parse"); - AST::current_filename = "input"; + // AST::current_filename = "input"; std::vector tokens; sigspec_parse_split(tokens, str, ','); @@ -5720,7 +5720,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri if (('0' <= netname[0] && netname[0] <= '9') || netname[0] == '\'') { cover("kernel.rtlil.sigspec.parse.const"); - VERILOG_FRONTEND::ConstParser p; + VERILOG_FRONTEND::ConstParser p{location()}; auto ast = p.const2ast(netname); if (ast == nullptr) return false;