Fixes issue where the correct file name was not printed out for semantic errors or warnings when processing .bin_fmt and .isa files. PiperOrigin-RevId: 672683580 Change-Id: Ibc517639e7001cf23e2c0266f0b994dcad047b47
diff --git a/mpact/sim/decoder/bin_format_visitor.cc b/mpact/sim/decoder/bin_format_visitor.cc index 605b0f5..ff1fdda 100644 --- a/mpact/sim/decoder/bin_format_visitor.cc +++ b/mpact/sim/decoder/bin_format_visitor.cc
@@ -21,6 +21,7 @@ #include <istream> #include <list> #include <memory> +#include <new> #include <string> #include <utility> #include <vector> @@ -129,6 +130,7 @@ // Create and add the error listener. set_error_listener(std::make_unique<decoder::DecoderErrorListener>()); error_listener_->set_file_name(file_names[0]); + file_names_.push_back(file_names[0]); parser_wrapper.parser()->removeErrorListeners(); parser_wrapper.parser()->addErrorListener(error_listener()); @@ -365,7 +367,7 @@ for (auto iter = reference_map.lower_bound(format->name()); iter != reference_map.upper_bound(format->name()); iter++) { std::string parent_format_name = iter->second; - VisitFormatDef(format_decl_map_[parent_format_name], + VisitFormatDef(format_decl_map_.at(parent_format_name), bin_encoding_info.get()); format_list.push_back(bin_encoding_info->GetFormat(parent_format_name)); } @@ -378,9 +380,11 @@ std::vector<IncludeFileCtx *> include_files; for (auto *declaration : ctx->declaration()) { + context_file_map_.insert({declaration, current_file_index_}); // Create map from format name to format ctx. if (declaration->format_def() != nullptr) { auto format_def = declaration->format_def(); + context_file_map_.insert({format_def, current_file_index_}); auto name = format_def->name->getText(); auto iter = format_decl_map_.find(name); if (iter != format_decl_map_.end()) { @@ -396,6 +400,7 @@ // Create map from instruction group name to instruction group ctx. if (declaration->instruction_group_def() != nullptr) { auto group_def = declaration->instruction_group_def(); + context_file_map_.insert({group_def, current_file_index_}); auto name = group_def->name->getText(); auto iter = group_decl_map_.find(name); if (iter != group_decl_map_.end()) { @@ -414,6 +419,7 @@ } // Create map from decoder name to decoder ctx. for (auto *decoder_def : ctx->decoder_def()) { + context_file_map_.insert({decoder_def, current_file_index_}); auto name = decoder_def->name->getText(); auto iter = decoder_decl_map_.find(name); if (iter != decoder_decl_map_.end()) { @@ -470,7 +476,10 @@ } } std::string previous_file_name = error_listener()->file_name(); + int previous_file_index_ = current_file_index_; error_listener()->set_file_name(file_name); + file_names_.push_back(file_name); + current_file_index_ = file_names_.size() - 1; auto *include_parser = new BinFmtAntlrParserWrapper(&include_file); // We need to save the parser state so it's available for analysis after // we are done with building the parse trees. @@ -482,13 +491,16 @@ DeclarationListCtx *declaration_list = include_parser->parser()->top_level()->declaration_list(); include_file.close(); - error_listener()->set_file_name(previous_file_name); if (error_listener()->syntax_error_count() > 0) { + error_listener()->set_file_name(previous_file_name); + current_file_index_ = previous_file_index_; return; } include_file_stack_.push_back(file_name); PreProcessDeclarations(declaration_list); include_file_stack_.pop_back(); + error_listener()->set_file_name(previous_file_name); + current_file_index_ = previous_file_index_; } void BinFormatVisitor::VisitFormatDef(FormatDefCtx *ctx, @@ -505,7 +517,7 @@ // Must specify either a width or it must inherit from a format that has // a width. error_listener_->semanticError( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("Format '", format_name, "': must specify a width or inherited format")); return; @@ -523,13 +535,14 @@ } if (parent_format == nullptr) { error_listener_->semanticError( - ctx->inherits_from()->start, + file_names_[context_file_map_.at(ctx)], ctx->inherits_from()->start, absl::StrCat("Parent format '", parent_name, "' not defined")); return; } else { int parent_width = parent_format->declared_width(); if ((format_width != -1) && (format_width != parent_width)) { error_listener_->semanticError( + file_names_[context_file_map_.at(format_decl_map_.at(parent_name))], ctx->inherits_from()->start, absl::StrCat("Format '", format_name, "' declared width (", format_width, ") differs from width inherited from '", @@ -544,21 +557,26 @@ format_res = encoding_info->AddFormat(format_name, format_width); } if (!format_res.ok()) { - error_listener_->semanticError(ctx->start, format_res.status().message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, format_res.status().message()); return; } // Parse the fields in the format. auto format = format_res.value(); + auto file_index = context_file_map_.at(ctx); for (auto field : ctx->format_field_defs()->field_def()) { + context_file_map_.insert({field, file_index}); VisitFieldDef(field, format, encoding_info); } // Parse the overlays in the format. for (auto overlay : ctx->format_field_defs()->overlay_def()) { + context_file_map_.insert({overlay, file_index}); VisitOverlayDef(overlay, format); } auto status = format->ComputeAndCheckFormatWidth(); if (!status.ok()) { - error_listener_->semanticError(ctx->start, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } } @@ -573,7 +591,8 @@ int width = ConvertToInt(ctx->index()->number()); auto status = format->AddField(field_name, is_signed, width); if (!status.ok()) { - error_listener_->semanticError(ctx->field_name, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->field_name, status.message()); } return; } @@ -607,25 +626,29 @@ // For now, only support overlays <= 64 bit wide. if (width > 64) { error_listener_->semanticError( - ctx->width->number()->start, + file_names_[context_file_map_.at(ctx)], ctx->width->number()->start, "Only overlays <= 64 bits are supported for now"); return; } // Visit the bitfield spec items. auto overlay_res = format->AddFieldOverlay(name, is_signed, width); if (!overlay_res.ok()) { - error_listener_->semanticError(ctx->start, overlay_res.status().message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, overlay_res.status().message()); return; } auto *overlay = overlay_res.value(); + int file_index = context_file_map_.at(ctx); for (auto *bit_field : ctx->bit_field_list()->bit_field_spec()) { + context_file_map_.insert({bit_field, file_index}); VisitOverlayBitField(bit_field, overlay); } if (overlay->computed_width() != overlay->declared_width()) { error_listener_->semanticError( - ctx->start, absl::StrCat("Declared width (", overlay->declared_width(), - ") differs from computed width (", - overlay->computed_width(), ")")); + file_names_[context_file_map_.at(ctx)], ctx->start, + absl::StrCat("Declared width (", overlay->declared_width(), + ") differs from computed width (", + overlay->computed_width(), ")")); } } @@ -643,13 +666,15 @@ auto status = overlay->AddFieldReference(ctx->IDENT()->getText(), std::move(bit_ranges_)); if (!status.ok()) { - error_listener_->semanticError(ctx->start, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } return; } auto status = overlay->AddFieldReference(ctx->IDENT()->getText()); if (!status.ok()) { - error_listener_->semanticError(ctx->start, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } return; } @@ -661,7 +686,8 @@ } auto status = overlay->AddFormatReference(std::move(bit_ranges_)); if (!status.ok()) { - error_listener_->semanticError(ctx->start, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } return; } @@ -680,14 +706,15 @@ auto format_iter = format_decl_map_.find(group_name); if (format_iter != format_decl_map_.end()) { error_listener_->semanticError( - ctx->start, absl::StrCat(group_name, ": illegal use of format name")); + file_names_[context_file_map_.at(ctx)], ctx->start, + absl::StrCat(group_name, ": illegal use of format name")); } int width = ConvertToInt(ctx->number()); std::string format_name = ctx->format->getText(); auto iter = format_decl_map_.find(format_name); if (iter == format_decl_map_.end()) { error_listener_->semanticError( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("Undefined format '", format_name, "' used by instruction group '", group_name, "'")); return nullptr; @@ -697,6 +724,7 @@ // Verify that the format width = declared width and also <= 64 bits wide. if (format->declared_width() != width) { error_listener_->semanticError( + file_names_[context_file_map_.at(format_decl_map_.at(format_name))], ctx->start, absl::StrCat("Width of format '", format_name, "' (", format->declared_width(), @@ -706,20 +734,25 @@ } if (format->declared_width() > 64) { error_listener_->semanticError( - ctx->start, absl::StrCat("Instruction group '", group_name, - "': width must be <= 64 bits")); + file_names_[context_file_map_.at(format_decl_map_.at(format_name))], + ctx->start, + absl::StrCat("Instruction group '", group_name, + "': width must be <= 64 bits")); } } auto inst_group_res = encoding_info->AddInstructionGroup(group_name, width, format_name); if (!inst_group_res.ok()) { - error_listener_->semanticError(ctx->start, + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, inst_group_res.status().message()); return nullptr; } // Parse the instruction encoding definitions in the instruction group. auto *inst_group = inst_group_res.value(); + int file_index = context_file_map_.at(ctx); for (auto *inst_def : ctx->instruction_def_list()->instruction_def()) { + context_file_map_.insert({inst_def, file_index}); VisitInstructionDef(inst_def, inst_group); } return inst_group_res.value(); @@ -741,7 +774,7 @@ auto iter = format_decl_map_.find(format_name); if (iter == format_decl_map_.end()) { error_listener_->semanticError( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("Format '", format_name, "' referenced by instruction '", name, "' not defined")); } else { @@ -752,7 +785,7 @@ if ((format != nullptr) && (format->declared_width() != inst_group->width())) { error_listener_->semanticError( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat( "Length of format '", format_name, "' (", format->declared_width(), ") differs from the declared width of the instruction group (", @@ -762,7 +795,9 @@ inst_group->AddInstructionEncoding(ctx->format_name, name, format); if (format == nullptr) return; // Add constraints to the instruction encoding. + int file_index = context_file_map_.at(ctx); for (auto *constraint : ctx->field_constraint_list()->field_constraint()) { + context_file_map_.insert({constraint, file_index}); VisitConstraint(format, constraint, inst_encoding); } } @@ -776,6 +811,7 @@ // value or a structured binding assignment. If it's a binding assignment we // need to make sure each tuple has the same number of values as there are // idents to assign them to. + int file_index = context_file_map_.at(ctx); for (auto *assign_ctx : ctx->range_assignment()) { auto *range_info = new RangeAssignmentInfo(); range_info_vec.push_back(range_info); @@ -783,7 +819,7 @@ std::string name = ident_ctx->getText(); if (range_variable_names.contains(name)) { error_listener()->semanticError( - assign_ctx->start, + file_names_[file_index], assign_ctx->start, absl::StrCat("Duplicate binding variable name '", name, "'")); continue; } @@ -796,7 +832,7 @@ if (!RE2::PartialMatch(ctx->generator_instruction_def_list()->getText(), range_info->range_regexes.back())) { error_listener()->semanticWarning( - assign_ctx->start, + file_names_[file_index], assign_ctx->start, absl::StrCat("Unreferenced binding variable '", name, "'.")); } } @@ -824,7 +860,7 @@ // Clean up. for (auto *info : range_info_vec) delete info; error_listener_->semanticError( - assign_ctx->start, + file_names_[file_index], assign_ctx->start, "Number of values differs from number of identifiers"); return; } @@ -856,7 +892,7 @@ auto ident = input_text.substr(start_pos, end_pos - start_pos); if (!range_variable_names.contains(ident)) { error_listener()->semanticError( - ctx->generator_instruction_def_list()->start, + file_names_[file_index], ctx->generator_instruction_def_list()->start, absl::StrCat("Undefined binding variable '", ident, "'")); } start_pos = end_pos; @@ -880,6 +916,7 @@ parser->parser()->instruction_def_list()->instruction_def(); // Process the opcode spec. for (auto *inst_def : instruction_defs) { + context_file_map_.insert({inst_def, file_index}); VisitInstructionDef(inst_def, inst_group); } // Clean up. @@ -938,14 +975,14 @@ if (field != nullptr) { if (field->width != length) { error_listener_->semanticWarning( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("Field '", field_name, "' has width ", field->width, " but constraint value is ", length, " bits")); } } else if (overlay != nullptr) { if (overlay->computed_width() != length) { error_listener_->semanticWarning( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("Overlay '", field_name, "' has width ", overlay->computed_width(), " but constraint value is ", length, " bits")); @@ -973,7 +1010,8 @@ value); } if (!status.ok()) { - error_listener_->semanticError(ctx->start, status.message()); + error_listener_->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } } @@ -992,12 +1030,14 @@ opcode_enum = opcode_enum_literal.substr(1, opcode_enum_literal.size() - 2); if (opcode_enum.empty()) { - error_listener_->semanticError(attr_ctx->start, - "Empty opcode enum string"); + file_names_[context_file_map_.at(ctx)], + error_listener_->semanticError(attr_ctx->start, + "Empty opcode enum string"); } if (opcode_count > 0) { - error_listener_->semanticError(attr_ctx->start, - "More than one opcode enum declaration"); + file_names_[context_file_map_.at(ctx)], + error_listener_->semanticError( + attr_ctx->start, "More than one opcode enum declaration"); } opcode_count++; } @@ -1024,8 +1064,9 @@ decoder->namespaces().push_back(namespace_name->getText()); } if (namespace_count > 0) { - error_listener_->semanticError(attr_ctx->start, - "More than one namespace declaration"); + file_names_[context_file_map_.at(ctx)], + error_listener_->semanticError( + attr_ctx->start, "More than one namespace declaration"); } namespace_count++; continue; @@ -1045,19 +1086,20 @@ } else { auto iter = group_decl_map_.find(group_name); if (iter != group_decl_map_.end()) { + context_file_map_.insert({iter->second, current_file_index_}); inst_group = VisitInstructionGroupDef(iter->second, encoding_info.get()); } if (inst_group == nullptr) { error_listener_->semanticError( - attr_ctx->start, + file_names_[context_file_map_.at(ctx)], attr_ctx->start, absl::StrCat("No such instruction group: '", group_name, "'")); continue; } } if (group_name_set.contains(group_name)) { error_listener_->semanticError( - attr_ctx->start, + file_names_[context_file_map_.at(ctx)], attr_ctx->start, absl::StrCat("Instruction group '", group_name, "' listed twice")); continue; } @@ -1073,8 +1115,9 @@ std::string group_name = attr_ctx->group_name()->IDENT()->getText(); if (group_name_set.contains(group_name)) { error_listener_->semanticError( - attr_ctx->start, absl::StrCat("Instruction group '", group_name, - "' listed twice - ignored")); + file_names_[context_file_map_.at(ctx)], attr_ctx->start, + absl::StrCat("Instruction group '", group_name, + "' listed twice - ignored")); continue; } std::vector<InstructionGroup *> child_groups; @@ -1084,8 +1127,9 @@ auto child_name = ident->getText(); if (group_name_set.contains(child_name)) { error_listener_->semanticError( - attr_ctx->start, absl::StrCat("Instruction group listed twice: '", - child_name, "' - ignored")); + file_names_[context_file_map_.at(ctx)], attr_ctx->start, + absl::StrCat("Instruction group listed twice: '", child_name, + "' - ignored")); continue; } InstructionGroup *child_group = nullptr; @@ -1101,8 +1145,9 @@ } if (exists) { error_listener_->semanticError( - attr_ctx->start, absl::StrCat("Instruction group '", child_name, - "' listed twice")); + file_names_[context_file_map_.at(ctx)], attr_ctx->start, + absl::StrCat("Instruction group '", child_name, + "' listed twice")); continue; } } else { @@ -1115,7 +1160,7 @@ } if (child_group == nullptr) { error_listener_->semanticError( - attr_ctx->start, + file_names_[context_file_map_.at(ctx)], attr_ctx->start, absl::StrCat("Instruction group '", child_name, "' not found")); continue; } @@ -1126,7 +1171,7 @@ // Check that the child groups all use the same instruction format. if (group_format_name != child_group->format_name()) { error_listener_->semanticError( - attr_ctx->start, + file_names_[context_file_map_.at(ctx)], attr_ctx->start, absl::StrCat("Instruction group '", child_name, "' must use format '", group_format_name, ", to be merged into group '", group_name, "'"));
diff --git a/mpact/sim/decoder/bin_format_visitor.h b/mpact/sim/decoder/bin_format_visitor.h index 68ac713..25a99bb 100644 --- a/mpact/sim/decoder/bin_format_visitor.h +++ b/mpact/sim/decoder/bin_format_visitor.h
@@ -136,6 +136,11 @@ error_listener_ = std::move(listener); } + int current_file_index_ = 0; + // Vector of file names. + std::vector<std::string> file_names_; + // Map from context pointer to file index. + absl::flat_hash_map<const antlr4::ParserRuleContext *, int> context_file_map_; // This stores a vector of include file root directories. std::vector<std::string> include_dir_vec_; // Keep track of files that are included in case there is recursive includes.
diff --git a/mpact/sim/decoder/decoder_error_listener.cc b/mpact/sim/decoder/decoder_error_listener.cc index 3f2e17e..10335b3 100644 --- a/mpact/sim/decoder/decoder_error_listener.cc +++ b/mpact/sim/decoder/decoder_error_listener.cc
@@ -29,10 +29,21 @@ // Error listener methods. void DecoderErrorListener::semanticError(antlr4::Token *token, absl::string_view msg) { + semanticError(file_name_, token, msg); +} + +void DecoderErrorListener::semanticWarning(antlr4::Token *token, + absl::string_view msg) { + semanticWarning(file_name_, token, msg); +} + +void DecoderErrorListener::semanticError(const std::string &file_name, + antlr4::Token *token, + absl::string_view msg) { if (token != nullptr) { size_t line = token->getLine(); size_t charPositionInLine = token->getCharPositionInLine(); - LOG(ERROR) << absl::StrCat(file_name_, ":", line, ":", charPositionInLine, + LOG(ERROR) << absl::StrCat(file_name, ":", line, ":", charPositionInLine, " Error: ", msg, "\n"); } else { LOG(ERROR) << absl::StrCat("Error: ", msg, "\n"); @@ -40,12 +51,13 @@ semantic_error_count_++; } -void DecoderErrorListener::semanticWarning(antlr4::Token *token, +void DecoderErrorListener::semanticWarning(const std::string &file_name, + antlr4::Token *token, absl::string_view msg) { if (token != nullptr) { size_t line = token->getLine(); size_t charPositionInLine = token->getCharPositionInLine(); - LOG(WARNING) << absl::StrCat(file_name_, ":", line, ":", charPositionInLine, + LOG(WARNING) << absl::StrCat(file_name, ":", line, ":", charPositionInLine, " Warning: ", msg, "\n"); } else { LOG(WARNING) << absl::StrCat("Warning: ", msg, "\n");
diff --git a/mpact/sim/decoder/decoder_error_listener.h b/mpact/sim/decoder/decoder_error_listener.h index e981529..77eb3d8 100644 --- a/mpact/sim/decoder/decoder_error_listener.h +++ b/mpact/sim/decoder/decoder_error_listener.h
@@ -34,6 +34,10 @@ public: void semanticError(antlr4::Token *token, absl::string_view msg); void semanticWarning(antlr4::Token *token, absl::string_view msg); + void semanticError(const std::string &file_name, antlr4::Token *token, + absl::string_view msg); + void semanticWarning(const std::string &file_name, antlr4::Token *token, + absl::string_view msg); void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine, const std::string &msg,
diff --git a/mpact/sim/decoder/instruction.h b/mpact/sim/decoder/instruction.h index 01fc4ee..a04ab90 100644 --- a/mpact/sim/decoder/instruction.h +++ b/mpact/sim/decoder/instruction.h
@@ -78,6 +78,7 @@ // Getters and setters. Opcode *opcode() const { return opcode_; } Instruction *child() const { return child_; } + Slot *slot() const { return slot_; } void set_semfunc_code_string(std::string code_string) { semfunc_code_string_ = code_string; }
diff --git a/mpact/sim/decoder/instruction_set_visitor.cc b/mpact/sim/decoder/instruction_set_visitor.cc index 31f9792..579f96c 100644 --- a/mpact/sim/decoder/instruction_set_visitor.cc +++ b/mpact/sim/decoder/instruction_set_visitor.cc
@@ -110,6 +110,7 @@ // Create an antlr4 stream from the input stream. IsaAntlrParserWrapper parser_wrapper(source_stream); error_listener()->set_file_name(file_names[0]); + file_names_.push_back(file_names[0]); parser_wrapper.parser()->removeErrorListeners(); parser_wrapper.parser()->addErrorListener(error_listener()); @@ -248,17 +249,20 @@ // Process disasm widths. Only the one in the top level file is used if there // are additional ones in included files. int count = 0; - std::string location; + DisasmWidthsCtx *disasm_ctx = nullptr; for (auto *decl : declarations) { + context_file_map_[decl] = current_file_index_; if (decl->disasm_widths() == nullptr) continue; if (count > 0) { error_listener()->semanticError( - nullptr, absl::StrCat("Only one `disasm width` declaration allowed - " - "previous declaration on line: ", - location)); + decl->disasm_widths()->start, + absl::StrCat("Only one `disasm width` declaration allowed - " + "previous declaration on line: ", + disasm_ctx->start->getLine())); } + disasm_ctx = decl->disasm_widths(); + context_file_map_[disasm_ctx] = context_file_map_.at(decl); VisitDisasmWidthsDecl(decl->disasm_widths()); - location = absl::StrCat(decl->start->getLine()); count++; } @@ -290,6 +294,7 @@ for (auto *decl : ctx_vec) { if (decl->slot_declaration() != nullptr) { auto *slot_ctx = decl->slot_declaration(); + context_file_map_.insert({slot_ctx, current_file_index_}); auto name = slot_ctx->slot_name->getText(); auto ptr = slot_decl_map_.find(name); if (ptr != slot_decl_map_.end()) { @@ -304,6 +309,7 @@ // Create map from bundle name to bundle ctx. if (decl->bundle_declaration() != nullptr) { auto *bundle_ctx = decl->bundle_declaration(); + context_file_map_.insert({bundle_ctx, current_file_index_}); auto name = bundle_ctx->bundle_name->getText(); auto ptr = bundle_decl_map_.find(name); if (ptr != bundle_decl_map_.end()) { @@ -319,6 +325,7 @@ // Create map from isa name to isa ctx. if (decl->isa_declaration() != nullptr) { auto *isa_ctx = decl->isa_declaration(); + context_file_map_.insert({isa_ctx, current_file_index_}); auto name = isa_ctx->instruction_set_name->getText(); auto ptr = isa_decl_map_.find(name); if (ptr != isa_decl_map_.end()) { @@ -343,6 +350,7 @@ // Process global constants. if (decl->constant_def() != nullptr) { + context_file_map_.insert({decl->constant_def(), current_file_index_}); VisitConstantDef(decl->constant_def()); } @@ -370,7 +378,9 @@ // Visit the namespace declaration, and the bundle and slot references that // are part of the instruction_set declaration. VisitNamespaceDecl(ctx->namespace_decl(), instruction_set.get()); + context_file_map_[ctx->bundle_list()] = context_file_map_.at(ctx); VisitBundleList(ctx->bundle_list(), instruction_set->bundle()); + context_file_map_[ctx->slot_list()] = context_file_map_.at(ctx); VisitSlotList(ctx->slot_list(), instruction_set->bundle()); return instruction_set; } @@ -394,7 +404,7 @@ // If the name hasn't been seen, flag an error. if (iter == bundle_decl_map_.end()) { error_listener()->semanticError( - bundle_spec->start, + file_names_[context_file_map_.at(ctx)], bundle_spec->start, absl::StrCat("Reference to undefined bundle: '", bundle_name, "'")); continue; } @@ -416,7 +426,7 @@ // If the slot hasn't been seen, flag an error. if (iter == slot_decl_map_.end()) { error_listener()->semanticError( - slot_spec->start, + file_names_[context_file_map_.at(ctx)], slot_spec->start, absl::StrCat("Reference to undefined slot: '", slot_name, "'")); continue; } @@ -457,6 +467,7 @@ if (ctx == nullptr) return; std::string ident = ctx->ident()->getText(); std::string type = ctx->template_parameter_type()->getText(); + context_file_map_.insert({ctx->expression(), context_file_map_.at(ctx)}); auto *expr = VisitExpression(ctx->expression(), nullptr, nullptr); auto status = AddConstant(ident, type, expr); if (!status.ok()) { @@ -504,7 +515,10 @@ } } std::string previous_file_name = error_listener()->file_name(); + int previous_file_index_ = current_file_index_; error_listener()->set_file_name(file_name); + file_names_.push_back(file_name); + current_file_index_ = file_names_.size() - 1; // Create an antlr4 stream from the input stream. auto *include_parser = new IsaAntlrParserWrapper(&include_file); // We need to save the parser state so it's available for analysis after @@ -517,13 +531,16 @@ auto declaration_vec = include_parser->parser()->include_top_level()->declaration(); include_file.close(); - error_listener()->set_file_name(previous_file_name); if (error_listener()->syntax_error_count() > 0) { + error_listener()->set_file_name(previous_file_name); + current_file_index_ = previous_file_index_; return; } include_file_stack_.push_back(file_name); PreProcessDeclarations(declaration_vec); include_file_stack_.pop_back(); + error_listener()->set_file_name(previous_file_name); + current_file_index_ = previous_file_index_; } void InstructionSetVisitor::VisitBundleDeclaration( @@ -532,7 +549,9 @@ Bundle *bundle = new Bundle(ctx->bundle_name->getText(), instruction_set, ctx); instruction_set->AddBundle(bundle); + context_file_map_[ctx->bundle_list()] = context_file_map_.at(ctx); VisitBundleList(ctx->bundle_list(), bundle); + context_file_map_[ctx->slot_list()] = context_file_map_.at(ctx); VisitSlotList(ctx->slot_list(), bundle); } @@ -545,7 +564,9 @@ for (auto const ¶m : ctx->template_decl()->template_parameter_decl()) { auto status = slot->AddTemplateFormal(param->IDENT()->getText()); if (!status.ok()) { - error_listener()->semanticError(param->start, status.message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], param->start, + status.message()); } } } @@ -558,7 +579,8 @@ auto slot_iter = slot_decl_map_.find(base_name); if (slot_iter == slot_decl_map_.end()) { error_listener()->semanticError( - base_item->start, absl::StrCat("Undefined base slot: ", base_name)); + file_names_[context_file_map_.at(ctx)], base_item->start, + absl::StrCat("Undefined base slot: ", base_name)); continue; } // If the slot hasn't been visited, visit it. @@ -573,14 +595,14 @@ if ((template_spec != nullptr) && !base->is_templated()) { // Template arguments are present but the slot isn't templated. error_listener()->semanticError( - base_item->start, + file_names_[context_file_map_.at(ctx)], base_item->start, absl::StrCat("'", base_name, "' is not a templated slot")); continue; } if ((template_spec == nullptr) && base->is_templated()) { // The slot is templated, but no template arguments. error_listener()->semanticError( - base_item->start, + file_names_[context_file_map_.at(ctx)], base_item->start, absl::StrCat("Missing template arguments for slot '", base_name, "'")); continue; @@ -591,7 +613,7 @@ int param_count = base->template_parameters().size(); if (arg_count != param_count) { error_listener()->semanticError( - template_spec->start, + file_names_[context_file_map_.at(ctx)], template_spec->start, absl::StrCat("Wrong number of arguments: ", param_count, " were expected, ", arg_count, " were provided")); continue; @@ -600,10 +622,12 @@ // Build up the argument vector. auto *arguments = new TemplateInstantiationArgs; for (auto *template_arg : template_spec->expression()) { + context_file_map_.insert({template_arg, context_file_map_.at(ctx)}); auto *expr = VisitExpression(template_arg, slot, nullptr); if (expr == nullptr) { - error_listener()->semanticError(template_arg->start, - "Error in template expression"); + error_listener()->semanticError( + file_names_[context_file_map_.at(ctx)], template_arg->start, + "Error in template expression"); has_error = true; break; } @@ -618,13 +642,17 @@ } auto result = slot->AddBase(base, arguments); if (!result.ok()) { - error_listener()->semanticError(base_item->start, result.message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(ctx)], base_item->start, + result.message()); } } else { // No template arguments. auto result = slot->AddBase(base); if (!result.ok()) { - error_listener()->semanticError(base_item->start, result.message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(ctx)], base_item->start, + result.message()); } } } @@ -637,13 +665,16 @@ // Add the slot to the ISA. instruction_set->AddSlot(slot); for (auto *decl_ctx : ctx->const_and_default_decl()) { + context_file_map_[decl_ctx] = context_file_map_.at(ctx); VisitConstAndDefaultDecls(decl_ctx, slot); } + context_file_map_[ctx->opcode_list()] = context_file_map_.at(ctx); VisitOpcodeList(ctx->opcode_list(), slot); } void InstructionSetVisitor::VisitDisasmWidthsDecl(DisasmWidthsCtx *ctx) { for (auto *expr : ctx->expression()) { + context_file_map_.insert({expr, context_file_map_.at(ctx)}); auto *width_expr = VisitExpression(expr, nullptr, nullptr); if ((width_expr == nullptr) || (!width_expr->IsConstant())) { error_listener()->semanticError(expr->start, @@ -662,17 +693,21 @@ if (const_def != nullptr) { // Constant declaration. std::string ident = const_def->ident()->getText(); std::string type = const_def->template_parameter_type()->getText(); + context_file_map_.insert( + {const_def->expression(), context_file_map_.at(ctx)}); auto *expr = VisitExpression(const_def->expression(), slot, nullptr); if (expr == nullptr) { delete expr; - error_listener()->semanticError(const_def->expression()->start, + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + const_def->expression()->start, "Error in expression"); return; } auto status = slot->AddConstant(ident, type, expr); if (!status.ok()) { delete expr; - error_listener()->semanticError(const_def->ident()->start, + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + const_def->ident()->start, status.message()); } return; @@ -683,10 +718,12 @@ return; } if (ctx->LATENCY() != nullptr) { // Default latency. + context_file_map_.insert({ctx->expression(), context_file_map_.at(ctx)}); auto *expr = VisitExpression(ctx->expression(), slot, nullptr); if (expr == nullptr) { delete expr; - error_listener()->semanticError(ctx->expression()->start, + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->expression()->start, "Error in expression"); return; } @@ -694,6 +731,8 @@ return; } if (ctx->ATTRIBUTES() != nullptr) { // Default attributes. + context_file_map_.insert( + {ctx->instruction_attribute_list(), context_file_map_.at(ctx)}); VisitInstructionAttributeList(ctx->instruction_attribute_list(), slot, nullptr); return; @@ -711,7 +750,8 @@ // and semantic function for when no valid opcode is found during decode. if (slot->default_instruction() != nullptr) { error_listener()->semanticError( - ctx->start, "Multiple definitions of 'default' opcode"); + file_names_[context_file_map_.at(ctx)], ctx->start, + "Multiple definitions of 'default' opcode"); return; } auto *default_instruction = new Instruction( @@ -722,8 +762,9 @@ // Disasm spec. if (attribute->disasm_spec() != nullptr) { if (has_disasm) { - error_listener()->semanticError(attribute->start, - "Duplicate disasm declaration"); + error_listener()->semanticError( + file_names_[context_file_map_.at(ctx)], attribute->start, + "Duplicate disasm declaration"); continue; } has_disasm = true; @@ -743,7 +784,8 @@ // Semfunc spec. // If a semfunc has already been declared, signal an error. if (has_semfunc) { - error_listener()->semanticError(attribute->start, + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + attribute->start, "Duplicate semfunc declaration"); continue; } @@ -753,7 +795,8 @@ // opcode. if (semfunc_code.size() > 1) { error_listener()->semanticError( - ctx->start, "Only one semfunc specification per default opcode"); + file_names_[context_file_map_.at(ctx)], ctx->start, + "Only one semfunc specification per default opcode"); continue; } std::string string_literal = semfunc_code[0]->getText(); @@ -767,14 +810,15 @@ } else { delete default_instruction; error_listener()->semanticError( - ctx->start, "Default opcode lacks mandatory semfunc specification"); + file_names_[context_file_map_.at(ctx)], ctx->start, + "Default opcode lacks mandatory semfunc specification"); } } if (ctx->resource_details() != nullptr) { std::string ident = ctx->ident()->getText(); if (slot->resource_spec_map().contains(ident)) { error_listener()->semanticError( - ctx->ident()->start, + file_names_[context_file_map_.at(ctx)], ctx->ident()->start, absl::StrCat("Resources '", ident, "': duplicate definition")); return; } @@ -792,6 +836,7 @@ Instruction *inst) { if (ctx == nullptr) return nullptr; if (ctx->negop() != nullptr) { + context_file_map_.insert({ctx->expr, context_file_map_.at(ctx)}); TemplateExpression *expr = VisitExpression(ctx->expr, slot, inst); if (expr == nullptr) return nullptr; return new TemplateNegate(expr); @@ -799,8 +844,10 @@ if (ctx->mulop() != nullptr) { std::string op = ctx->mulop()->getText(); + context_file_map_.insert({ctx->lhs, context_file_map_.at(ctx)}); TemplateExpression *lhs = VisitExpression(ctx->lhs, slot, inst); if (lhs == nullptr) return nullptr; + context_file_map_.insert({ctx->rhs, context_file_map_.at(ctx)}); TemplateExpression *rhs = VisitExpression(ctx->rhs, slot, inst); if (rhs == nullptr) { delete lhs; @@ -812,8 +859,10 @@ if (ctx->addop() != nullptr) { std::string op = ctx->addop()->getText(); + context_file_map_.insert({ctx->lhs, context_file_map_.at(ctx)}); TemplateExpression *lhs = VisitExpression(ctx->lhs, slot, inst); if (lhs == nullptr) return nullptr; + context_file_map_.insert({ctx->rhs, context_file_map_.at(ctx)}); TemplateExpression *rhs = VisitExpression(ctx->rhs, slot, inst); if (rhs == nullptr) { delete lhs; @@ -828,19 +877,22 @@ auto iter = template_function_evaluators_.find(function); if (iter == template_function_evaluators_.end()) { error_listener()->semanticError( - ctx->start, absl::StrCat("No function '", function, "' supported")); + file_names_[context_file_map_.at(ctx)], ctx->start, + absl::StrCat("No function '", function, "' supported")); return nullptr; } auto evaluator = iter->second; if (ctx->expression().size() != evaluator.arity) { error_listener()->semanticError( - ctx->start, absl::StrCat("Function '", function, "' takes ", - evaluator.arity, " parameters, but ", - ctx->expression().size(), " were given")); + file_names_[context_file_map_.at(ctx)], ctx->start, + absl::StrCat("Function '", function, "' takes ", evaluator.arity, + " parameters, but ", ctx->expression().size(), + " were given")); } auto *args = new TemplateInstantiationArgs; bool has_error = false; for (auto *expr_ctx : ctx->expression()) { + context_file_map_.insert({expr_ctx, context_file_map_.at(ctx)}); auto *expr = VisitExpression(expr_ctx, slot, inst); if (expr == nullptr) { has_error = true; @@ -859,6 +911,7 @@ } if (ctx->paren_expr != nullptr) { + context_file_map_.insert({ctx->paren_expr, context_file_map_.at(ctx)}); return VisitExpression(ctx->paren_expr, slot, inst); } @@ -888,7 +941,7 @@ auto *op = inst->GetDestOp(ident); if (op == nullptr) { error_listener()->semanticError( - ctx->start, + file_names_[context_file_map_.at(ctx)], ctx->start, absl::StrCat("'", ident, "' is not a valid destination operand for opcode '", inst->opcode()->name(), "'")); @@ -901,7 +954,8 @@ // expr is null, this means that the destination operand has a decode // time computed latency. This is a special case that will be addressed // later. For now, signal an unsupported error. - error_listener()->semanticError(ctx->start, + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, "Decode time evaluation of latency " "expression not supported for resources"); return nullptr; @@ -911,20 +965,24 @@ if (expr != nullptr) return expr->DeepCopy(); error_listener()->semanticError( - ctx->start, absl::StrCat("Unable to evaluate expression: ", "'", - ctx->getText(), "'")); + file_names_[context_file_map_.at(ctx)], ctx->start, + absl::StrCat("Unable to evaluate expression: ", "'", ctx->getText(), + "'")); } return nullptr; } DestinationOperand *InstructionSetVisitor::FindDestinationOpInExpression( - ExpressionCtx *ctx, const Slot *slot, const Instruction *inst) const { + ExpressionCtx *ctx, const Slot *slot, const Instruction *inst) { if (ctx == nullptr) return nullptr; if (ctx->negop() != nullptr) { + context_file_map_.insert({ctx->expr, context_file_map_.at(ctx)}); return FindDestinationOpInExpression(ctx->expr, slot, inst); } if ((ctx->mulop() != nullptr) || (ctx->addop() != nullptr)) { + context_file_map_.insert({ctx->lhs, context_file_map_.at(ctx)}); + context_file_map_.insert({ctx->rhs, context_file_map_.at(ctx)}); auto *lhs = FindDestinationOpInExpression(ctx->lhs, slot, inst); auto *rhs = FindDestinationOpInExpression(ctx->rhs, slot, inst); if (lhs == nullptr) return rhs; @@ -938,6 +996,7 @@ return nullptr; } if (ctx->paren_expr != nullptr) { + context_file_map_.insert({ctx->paren_expr, context_file_map_.at(ctx)}); return FindDestinationOpInExpression(ctx->paren_expr, slot, inst); } if (ctx->NUMBER() != nullptr) { @@ -947,6 +1006,7 @@ DestinationOperand *dest_op = nullptr; DestinationOperand *tmp_op; for (auto *expr_ctx : ctx->expression()) { + context_file_map_.insert({expr_ctx, context_file_map_.at(ctx)}); tmp_op = FindDestinationOpInExpression(expr_ctx, slot, inst); if (dest_op == nullptr) { dest_op = tmp_op; @@ -997,7 +1057,9 @@ absl::Status status = slot->AppendInheritedInstruction(inst_ptr, base_slot.arguments); if (!status.ok()) { - error_listener()->semanticError(ctx->start, status.message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(ctx)], ctx->start, + status.message()); } } } @@ -1008,7 +1070,8 @@ for (auto *inst : instruction_vec) { absl::Status status = slot->AppendInstruction(inst); if (!status.ok()) { - error_listener()->semanticError(ctx->start, status.message()); + error_listener()->semanticError(file_names_[context_file_map_.at(ctx)], + ctx->start, status.message()); } } } @@ -1039,8 +1102,9 @@ inst->ClearDisasmFormat(); // Signal error if there is more than one disassembly spec. if (has_disasm) { - error_listener()->semanticError(attribute_ctx->start, - "Multiple disasm specifications"); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], + attribute_ctx->start, "Multiple disasm specifications"); continue; } has_disasm = true; @@ -1051,8 +1115,9 @@ format.erase(0, 1); auto status = ParseDisasmFormat(format, inst); if (!status.ok()) { - error_listener()->semanticError(attribute_ctx->disasm_spec()->start, - status.message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], + attribute_ctx->disasm_spec()->start, status.message()); has_disasm = false; break; } @@ -1066,8 +1131,9 @@ inst->ClearSemfuncCodeString(); // Signal error if there is more than one semantic function spec. if (has_semfunc) { - error_listener()->semanticError(attribute_ctx->start, - "Multiple semfunc specifications"); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], + attribute_ctx->start, "Multiple semfunc specifications"); continue; } has_semfunc = true; @@ -1081,8 +1147,9 @@ inst->ClearResourceSpecs(); // Signal error if there is more than one resource specification. if (has_resources) { - error_listener()->semanticError(attribute_ctx->start, - "Multiple resource specifications"); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], + attribute_ctx->start, "Multiple resource specifications"); continue; } has_resources = true; @@ -1097,8 +1164,9 @@ inst->ClearAttributeSpecs(); // Signal error if there is more than one attribute specification. if (has_attributes) { - error_listener()->semanticError(attribute_ctx->start, - "Multiple attribute specifications"); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], + attribute_ctx->start, "Multiple attribute specifications"); continue; } has_attributes = true; @@ -1109,8 +1177,9 @@ } // Unknown attribute type. - error_listener()->semanticError(attribute_ctx->start, - "Unknown attribute type"); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], attribute_ctx->start, + "Unknown attribute type"); } } @@ -1121,12 +1190,14 @@ std::string name = attribute->IDENT()->getText(); if (attributes.find(name) != attributes.end()) { error_listener()->semanticError( - attribute->start, + file_names_[context_file_map_.at(slot->ctx())], attribute->start, absl::StrCat("Duplicate attribute name '", name, "' in list")); continue; } InstructionSet::AddAttributeName(name); if (attribute->expression() != nullptr) { + context_file_map_.insert( + {attribute->expression(), context_file_map_.at(slot->ctx())}); auto *expr = VisitExpression(attribute->expression(), slot, inst); attributes.emplace(name, expr); continue; @@ -1158,8 +1229,9 @@ // should be one the opcode and one for each child opcode. for (auto *sem_func : semfunc_spec->STRING_LITERAL()) { if (child == nullptr) { - error_listener()->semanticWarning(sem_func->getSymbol(), - "Ignoring extra semfunc spec"); + error_listener()->semanticWarning( + file_names_[context_file_map_.at(inst->slot()->ctx())], + sem_func->getSymbol(), "Ignoring extra semfunc spec"); break; } std::string literal = sem_func->getText(); @@ -1170,6 +1242,7 @@ // Are there fewer specifier strings than child instructions? if (child != nullptr) { error_listener()->semanticError( + file_names_[context_file_map_.at(inst->slot()->ctx())], semfunc_spec->start, absl::StrCat("Fewer semfunc specifiers than expected for opcode '", inst->opcode()->name(), "'")); @@ -1186,7 +1259,7 @@ if (iter == slot->resource_spec_map().end()) { // This should never happen. error_listener()->semanticError( - ctx->start, + file_names_[context_file_map_.at(slot->ctx())], ctx->start, absl::StrCat("Internal error: Undefined resources name: '", name, "'")); return; @@ -1222,6 +1295,8 @@ if (resource_item->begin_cycle == nullptr) { begin_expr = new TemplateConstant(0); } else { + context_file_map_.insert( + {resource_item->begin_cycle, context_file_map_.at(slot->ctx())}); tmp_op = FindDestinationOpInExpression(resource_item->begin_cycle, slot, inst); if (tmp_op != nullptr) { @@ -1229,12 +1304,15 @@ dest_op = tmp_op; } else if (dest_op != tmp_op) { error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], resource_item->start, "Resource reference can only reference a single " "destination operand"); return return_value; } } + context_file_map_.insert( + {resource_item->begin_cycle, context_file_map_.at(slot->ctx())}); begin_expr = VisitExpression(resource_item->begin_cycle, slot, inst); } @@ -1248,6 +1326,8 @@ end_expr = new TemplateConstant(0); } } else { + context_file_map_.insert( + {resource_item->end_cycle, context_file_map_.at(slot->ctx())}); tmp_op = FindDestinationOpInExpression(resource_item->end_cycle, slot, inst); if (tmp_op != nullptr) { @@ -1262,6 +1342,8 @@ return return_value; } } + context_file_map_.insert( + {resource_item->end_cycle, context_file_map_.at(slot->ctx())}); end_expr = VisitExpression(resource_item->end_cycle, slot, inst); } auto *ref = new ResourceReference(resource, dest_op, begin_expr, end_expr); @@ -1362,7 +1444,7 @@ // If there is no base slot, this is an error. if (slot->base_slots().empty()) { error_listener()->semanticError( - opcode_ctx->deleted, + file_names_[context_file_map_.at(slot->ctx())], opcode_ctx->deleted, absl::StrCat("Invalid deleted opcode '", opcode_name, "', slot '", slot->name(), "' does not inherit from a base slot")); return; @@ -1376,7 +1458,7 @@ // If the opcode was not defined in any of the base slots, it is an error. if (!found) { error_listener()->semanticError( - opcode_ctx->deleted, + file_names_[context_file_map_.at(slot->ctx())], opcode_ctx->deleted, absl::StrCat("Base slot does not define or inherit opcode '", opcode_name, "'")); return; @@ -1396,13 +1478,13 @@ // Multiple inheritance is not supported. if (found == 0) { error_listener()->semanticError( - opcode_ctx->deleted, + file_names_[context_file_map_.at(slot->ctx())], opcode_ctx->deleted, absl::StrCat("Base slot does not define or inherit opcode '", opcode_name, "'")); return; } else if (found > 1) { error_listener()->semanticError( - opcode_ctx->deleted, + file_names_[context_file_map_.at(slot->ctx())], opcode_ctx->deleted, absl::StrCat("Multiple inheritance of opcodes is not supported: ", opcode_name)); return; @@ -1414,8 +1496,9 @@ // This is a new opcode, so let's create it. Signal failure if error. absl::StatusOr<Opcode *> result = opcode_factory->CreateOpcode(opcode_name); if (!result.ok()) { - error_listener()->semanticError(opcode_ctx->name, - result.status().message()); + error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], opcode_ctx->name, + result.status().message()); return; } @@ -1507,6 +1590,8 @@ // expression, by '*' (wildcard), or omitted, in which case it // defaults to 1. if (dest_op->expression() != nullptr) { + context_file_map_.insert( + {dest_op->expression(), context_file_map_.at(slot->ctx())}); child->opcode()->AppendDestOp( ident, VisitExpression(dest_op->expression(), slot, child)); } else if (dest_op->wildcard != nullptr) { @@ -1542,7 +1627,7 @@ std::string name = ident_ctx->getText(); if (range_variable_names.contains(name)) { error_listener()->semanticError( - assign_ctx->start, + file_names_[context_file_map_.at(slot->ctx())], assign_ctx->start, absl::StrCat("Duplicate binding variable name '", name, "'")); continue; } @@ -1555,7 +1640,7 @@ if (!RE2::PartialMatch(ctx->generator_opcode_spec_list()->getText(), range_info->range_regexes.back())) { error_listener()->semanticWarning( - assign_ctx->start, + file_names_[context_file_map_.at(slot->ctx())], assign_ctx->start, absl::StrCat("Unreferenced binding variable '", name, "'")); } } @@ -1606,6 +1691,7 @@ auto ident = input_text.substr(start_pos, end_pos - start_pos); if (!range_variable_names.contains(ident)) { error_listener()->semanticError( + file_names_[context_file_map_.at(slot->ctx())], ctx->generator_opcode_spec_list()->start, absl::StrCat("Undefined binding variable '", ident, "'")); }
diff --git a/mpact/sim/decoder/instruction_set_visitor.h b/mpact/sim/decoder/instruction_set_visitor.h index 4515b8f..5889a21 100644 --- a/mpact/sim/decoder/instruction_set_visitor.h +++ b/mpact/sim/decoder/instruction_set_visitor.h
@@ -141,8 +141,9 @@ void ParseIncludeFile(antlr4::ParserRuleContext *ctx, const std::string &file_name, const std::vector<std::string> &dirs); - DestinationOperand *FindDestinationOpInExpression( - ExpressionCtx *ctx, const Slot *slot, const Instruction *inst) const; + DestinationOperand *FindDestinationOpInExpression(ExpressionCtx *ctx, + const Slot *slot, + const Instruction *inst); void PerformOpcodeOverrides( absl::flat_hash_set<OpcodeSpecCtx *> overridden_ops_set, Slot *slot); void PreProcessDeclarations(const std::vector<DeclarationCtx *> &ctx_vec); @@ -209,6 +210,11 @@ // Include file strings. absl::btree_set<std::string> include_files_; + int current_file_index_ = 0; + // Vector of file names. + std::vector<std::string> file_names_; + // Map from context pointer to file index. + absl::flat_hash_map<antlr4::ParserRuleContext *, int> context_file_map_; // Include file roots. std::vector<std::string> include_dir_vec_; // Keep track of files that are included in case there is recursive includes.