From 52fa34a83139e80f61973ef128a496e8757c4238 Mon Sep 17 00:00:00 2001 From: slavek-kucera <53339291+slavek-kucera@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:17:30 +0200 Subject: [PATCH] refactor: Prune statement class hierarchy --- .../src/context/hlasm_statement.cpp | 4 - parser_library/src/context/hlasm_statement.h | 10 +- parser_library/src/context/literal_pool.cpp | 18 +-- .../ordinary_assembly/postponed_statement.h | 11 +- .../symbol_dependency_tables.cpp | 3 +- .../src/context/statement_cache.cpp | 13 +-- parser_library/src/context/statement_cache.h | 10 +- .../src/processing/error_statement.cpp | 4 - .../src/processing/error_statement.h | 4 +- .../instruction_sets/asm_processor.cpp | 2 +- .../instruction_sets/asm_processor.h | 2 +- .../instruction_sets/ca_processor.cpp | 64 +++++------ .../instruction_sets/ca_processor.h | 42 +++---- .../instruction_processor.cpp | 2 +- .../instruction_sets/instruction_processor.h | 2 +- .../low_language_processor.cpp | 3 +- .../instruction_sets/macro_processor.cpp | 6 +- .../postponed_statement_impl.h | 23 +--- .../src/processing/opencode_provider.cpp | 10 +- parser_library/src/processing/statement.h | 46 ++------ .../hit_count_analyzer.cpp | 36 +++--- .../statement_analyzers/hit_count_analyzer.h | 4 +- .../statement_analyzers/lsp_analyzer.cpp | 14 +-- .../lookahead_processor.cpp | 22 ++-- .../lookahead_processor.h | 2 +- .../macrodef_processor.cpp | 54 ++++++--- .../ordinary_processor.cpp | 4 +- .../members_statement_provider.cpp | 76 +++++++++--- .../members_statement_provider.h | 2 +- .../statement_provider.cpp | 2 +- parser_library/src/semantics/collector.cpp | 60 +++++++++- parser_library/src/semantics/statement.h | 108 +----------------- 32 files changed, 315 insertions(+), 348 deletions(-) diff --git a/parser_library/src/context/hlasm_statement.cpp b/parser_library/src/context/hlasm_statement.cpp index 8ceb9409e..29552a303 100644 --- a/parser_library/src/context/hlasm_statement.cpp +++ b/parser_library/src/context/hlasm_statement.cpp @@ -36,7 +36,3 @@ semantics::deferred_statement* hlasm_statement::access_deferred() { return kind == statement_kind::DEFERRED ? static_cast(this) : nullptr; } - -hlasm_statement::hlasm_statement(const statement_kind kind) - : kind(kind) -{} diff --git a/parser_library/src/context/hlasm_statement.h b/parser_library/src/context/hlasm_statement.h index 4b4a31927..6a63edff3 100644 --- a/parser_library/src/context/hlasm_statement.h +++ b/parser_library/src/context/hlasm_statement.h @@ -53,14 +53,16 @@ struct hlasm_statement const semantics::deferred_statement* access_deferred() const; semantics::deferred_statement* access_deferred(); - virtual position statement_position() const = 0; + position statement_position() const { return stmt_range_ref().start; } + virtual const range& stmt_range_ref() const = 0; virtual std::span diagnostics() const = 0; - virtual ~hlasm_statement() = default; - protected: - hlasm_statement(const statement_kind kind); + explicit hlasm_statement(const statement_kind kind) + : kind(kind) + {} + ~hlasm_statement() = default; }; using shared_stmt_ptr = std::shared_ptr; diff --git a/parser_library/src/context/literal_pool.cpp b/parser_library/src/context/literal_pool.cpp index 127664b03..66e47558a 100644 --- a/parser_library/src/context/literal_pool.cpp +++ b/parser_library/src/context/literal_pool.cpp @@ -92,13 +92,12 @@ void literal_pool::mentioned_in_ca_expr(std::shared_ptr& dd, const literal_pool::literal_details& details) - : details(&details) + : context::postponed_statement(details.stack, this) , op(details.r, {}) - , op_code(context::id_index("DC"), instruction_type::ASM, nullptr) { op.value.push_back(std::make_unique(dd, details.r)); } - const processing_stack_t& location_stack() const override { return details->stack; } - const processing::resolved_statement* resolved_stmt() const override { return this; } + + const range& stmt_range_ref() const override { return op.field_range; } const processing::op_code& opcode_ref() const override { return op_code; } processing::processing_format format_ref() const override { return dc_format; } const semantics::operands_si& operands_ref() const override { return op; } std::span literals() const override { return {}; } const semantics::remarks_si& remarks_ref() const override { return empty_remarks; } - const range& stmt_range_ref() const override { return details->r; } const semantics::label_si& label_ref() const override { return empty_label; } const semantics::instruction_si& instruction_ref() const override { return empty_instr; } std::span diagnostics() const override { return {}; }; }; + +const processing::op_code literal_pool::literal_postponed_statement::op_code( + context::id_index("DC"), instruction_type::ASM, nullptr); const semantics::remarks_si literal_pool::literal_postponed_statement::empty_remarks({}, {}); const semantics::label_si literal_pool::literal_postponed_statement::empty_label(range {}); const semantics::instruction_si literal_pool::literal_postponed_statement::empty_instr(range {}); diff --git a/parser_library/src/context/ordinary_assembly/postponed_statement.h b/parser_library/src/context/ordinary_assembly/postponed_statement.h index 6ece6a15b..9bfdecfdc 100644 --- a/parser_library/src/context/ordinary_assembly/postponed_statement.h +++ b/parser_library/src/context/ordinary_assembly/postponed_statement.h @@ -15,8 +15,6 @@ #ifndef CONTEXT_POSTPONED_STATEMENT_H #define CONTEXT_POSTPONED_STATEMENT_H -#include - #include "context/source_context.h" namespace hlasm_plugin::parser_library::processing { @@ -29,9 +27,14 @@ namespace hlasm_plugin::parser_library::context { // contains stack of file positions from where was it postponed struct postponed_statement { - virtual const processing_stack_t& location_stack() const = 0; + postponed_statement(processing_stack_t location_stack, const processing::resolved_statement* resolved_stmt) + : location_stack(location_stack) + , resolved_stmt(resolved_stmt) + {} + + processing_stack_t location_stack; - virtual const processing::resolved_statement* resolved_stmt() const = 0; + const processing::resolved_statement* resolved_stmt; virtual ~postponed_statement() = default; }; diff --git a/parser_library/src/context/ordinary_assembly/symbol_dependency_tables.cpp b/parser_library/src/context/ordinary_assembly/symbol_dependency_tables.cpp index 709981648..4c614fc3c 100644 --- a/parser_library/src/context/ordinary_assembly/symbol_dependency_tables.cpp +++ b/parser_library/src/context/ordinary_assembly/symbol_dependency_tables.cpp @@ -140,8 +140,7 @@ struct resolve_dependant_visitor const auto add_diagnostic = [stmt, d = diag_consumer](auto f) { if (stmt) - d->add_diagnostic( - add_stack_details(f(stmt->resolved_stmt()->stmt_range_ref()), stmt->location_stack())); + d->add_diagnostic(add_stack_details(f(stmt->resolved_stmt->stmt_range_ref()), stmt->location_stack)); else d->add_diagnostic(add_stack_details(f(range()), {})); }; diff --git a/parser_library/src/context/statement_cache.cpp b/parser_library/src/context/statement_cache.cpp index 2e759cfc8..719936b84 100644 --- a/parser_library/src/context/statement_cache.cpp +++ b/parser_library/src/context/statement_cache.cpp @@ -22,17 +22,10 @@ statement_cache::statement_cache(shared_stmt_ptr base) : base_stmt_(std::move(base)) {} -bool statement_cache::contains(processing::processing_status_cache_key key) const +const statement_cache::cached_statement_t& statement_cache::insert( + processing::processing_status_cache_key key, cached_statement_t statement) { - for (const auto& entry : cache_) - if (entry.first == key) - return true; - return false; -} - -void statement_cache::insert(processing::processing_status_cache_key key, cached_statement_t statement) -{ - cache_.emplace_back(key, std::move(statement)); + return cache_.emplace_back(key, std::move(statement)).second; } const statement_cache::cached_statement_t* statement_cache::get(processing::processing_status_cache_key key) const diff --git a/parser_library/src/context/statement_cache.h b/parser_library/src/context/statement_cache.h index a8372008a..e6498c9b9 100644 --- a/parser_library/src/context/statement_cache.h +++ b/parser_library/src/context/statement_cache.h @@ -19,8 +19,8 @@ #include "hlasm_statement.h" #include "processing/op_code.h" -namespace hlasm_plugin::parser_library::semantics { -struct complete_statement; +namespace hlasm_plugin::parser_library::processing { +struct statement_si_defer_done; } namespace hlasm_plugin::parser_library::context { @@ -32,7 +32,7 @@ class statement_cache public: struct cached_statement_t { - std::shared_ptr stmt; + std::shared_ptr stmt; std::vector diags; }; // pair of processing format and reparsed statement @@ -46,9 +46,7 @@ class statement_cache public: statement_cache(shared_stmt_ptr base); - bool contains(processing::processing_status_cache_key key) const; - - void insert(processing::processing_status_cache_key key, cached_statement_t statement); + const cached_statement_t& insert(processing::processing_status_cache_key key, cached_statement_t statement); const cached_statement_t* get(processing::processing_status_cache_key key) const; diff --git a/parser_library/src/processing/error_statement.cpp b/parser_library/src/processing/error_statement.cpp index 50d0dc62d..008d06b5a 100644 --- a/parser_library/src/processing/error_statement.cpp +++ b/parser_library/src/processing/error_statement.cpp @@ -14,12 +14,8 @@ #include "error_statement.h" - namespace hlasm_plugin::parser_library::processing { - -position error_statement::statement_position() const { return m_range.start; } - std::span error_statement::diagnostics() const { return { m_errors.data(), m_errors.data() + m_errors.size() }; diff --git a/parser_library/src/processing/error_statement.h b/parser_library/src/processing/error_statement.h index 52cd81275..f59086d51 100644 --- a/parser_library/src/processing/error_statement.h +++ b/parser_library/src/processing/error_statement.h @@ -20,7 +20,7 @@ namespace hlasm_plugin::parser_library::processing { -class error_statement : public context::hlasm_statement +class error_statement final : public context::hlasm_statement { std::vector m_errors; range m_range; @@ -32,7 +32,7 @@ class error_statement : public context::hlasm_statement , m_range(r) {} - position statement_position() const override; + const range& stmt_range_ref() const override { return m_range; } std::span diagnostics() const override; }; diff --git a/parser_library/src/processing/instruction_sets/asm_processor.cpp b/parser_library/src/processing/instruction_sets/asm_processor.cpp index 96806c162..c8655cb08 100644 --- a/parser_library/src/processing/instruction_sets/asm_processor.cpp +++ b/parser_library/src/processing/instruction_sets/asm_processor.cpp @@ -758,7 +758,7 @@ void asm_processor::process(std::shared_ptr asm_processor::extract_copy_id( - const semantics::complete_statement& stmt, diagnosable_ctx* diagnoser) + const processing::resolved_statement& stmt, diagnosable_ctx* diagnoser) { if (stmt.operands_ref().value.size() != 1 || !stmt.operands_ref().value.front()->access_asm() || !stmt.operands_ref().value.front()->access_asm()->access_expr()) diff --git a/parser_library/src/processing/instruction_sets/asm_processor.h b/parser_library/src/processing/instruction_sets/asm_processor.h index f92baa5d1..a355ce621 100644 --- a/parser_library/src/processing/instruction_sets/asm_processor.h +++ b/parser_library/src/processing/instruction_sets/asm_processor.h @@ -72,7 +72,7 @@ class asm_processor : public low_language_processor range statement; }; static std::optional extract_copy_id( - const semantics::complete_statement& stmt, diagnosable_ctx* diagnoser); + const processing::resolved_statement& stmt, diagnosable_ctx* diagnoser); static bool common_copy_postprocess(bool processed, const extract_copy_id_result& data, context::hlasm_context& hlasm_ctx, diff --git a/parser_library/src/processing/instruction_sets/ca_processor.cpp b/parser_library/src/processing/instruction_sets/ca_processor.cpp index da5a19c41..2124c6584 100644 --- a/parser_library/src/processing/instruction_sets/ca_processor.cpp +++ b/parser_library/src/processing/instruction_sets/ca_processor.cpp @@ -81,7 +81,7 @@ ca_processor::process_table_t ca_processor::create_table() return table; } -void ca_processor::register_seq_sym(const semantics::complete_statement& stmt) +void ca_processor::register_seq_sym(const processing::resolved_statement& stmt) { if (stmt.label_ref().type == semantics::label_si_type::SEQ) { @@ -95,7 +95,7 @@ void ca_processor::register_seq_sym(const semantics::complete_statement& stmt) } template -ca_processor::SET_info ca_processor::get_SET_symbol(const semantics::complete_statement& stmt) +ca_processor::SET_info ca_processor::get_SET_symbol(const processing::resolved_statement& stmt) { if (stmt.label_ref().type != semantics::label_si_type::VAR) { @@ -167,12 +167,12 @@ ca_processor::SET_info ca_processor::get_SET_symbol(const semantics::complete_st return SET_info { set_sym, name, index }; } -template ca_processor::SET_info ca_processor::get_SET_symbol(const semantics::complete_statement& stmt); -template ca_processor::SET_info ca_processor::get_SET_symbol(const semantics::complete_statement& stmt); -template ca_processor::SET_info ca_processor::get_SET_symbol(const semantics::complete_statement& stmt); +template ca_processor::SET_info ca_processor::get_SET_symbol(const processing::resolved_statement& stmt); +template ca_processor::SET_info ca_processor::get_SET_symbol(const processing::resolved_statement& stmt); +template ca_processor::SET_info ca_processor::get_SET_symbol(const processing::resolved_statement& stmt); bool ca_processor::prepare_SET_operands( - const semantics::complete_statement& stmt, std::vector& expr_values) + const processing::resolved_statement& stmt, std::vector& expr_values) { const auto& ops = stmt.operands_ref().value; if (ops.empty()) @@ -203,7 +203,7 @@ bool ca_processor::prepare_SET_operands( return true; } -bool ca_processor::prepare_GBL_LCL(const semantics::complete_statement& stmt, std::vector& info) const +bool ca_processor::prepare_GBL_LCL(const processing::resolved_statement& stmt, std::vector& info) const { bool has_operand = false; const auto& ops = stmt.operands_ref().value; @@ -257,13 +257,13 @@ bool ca_processor::prepare_GBL_LCL(const semantics::complete_statement& stmt, st return true; } -void ca_processor::process_ANOP(const semantics::complete_statement& stmt) +void ca_processor::process_ANOP(const processing::resolved_statement& stmt) { assert(stmt.operands_ref().value.empty()); register_seq_sym(stmt); } -void ca_processor::process_ACTR(const semantics::complete_statement& stmt) +void ca_processor::process_ACTR(const processing::resolved_statement& stmt) { register_seq_sym(stmt); @@ -293,7 +293,7 @@ void ca_processor::process_ACTR(const semantics::complete_statement& stmt) } } -const semantics::seq_sym* ca_processor::prepare_AGO(const semantics::complete_statement& stmt) +const semantics::seq_sym* ca_processor::prepare_AGO(const processing::resolved_statement& stmt) { const auto& ops = stmt.operands_ref().value; if (ops.empty()) @@ -354,7 +354,7 @@ const semantics::seq_sym* ca_processor::prepare_AGO(const semantics::complete_st return nullptr; } -void ca_processor::process_AGO(const semantics::complete_statement& stmt) +void ca_processor::process_AGO(const processing::resolved_statement& stmt) { register_seq_sym(stmt); @@ -362,7 +362,7 @@ void ca_processor::process_AGO(const semantics::complete_statement& stmt) branch_provider.jump_in_statements(target->name, target->symbol_range); } -const semantics::seq_sym* ca_processor::prepare_AIF(const semantics::complete_statement& stmt) +const semantics::seq_sym* ca_processor::prepare_AIF(const processing::resolved_statement& stmt) { const auto& ops = stmt.operands_ref().value; if (ops.empty()) @@ -413,7 +413,7 @@ const semantics::seq_sym* ca_processor::prepare_AIF(const semantics::complete_st return result; } -void ca_processor::process_AIF(const semantics::complete_statement& stmt) +void ca_processor::process_AIF(const processing::resolved_statement& stmt) { register_seq_sym(stmt); @@ -421,13 +421,13 @@ void ca_processor::process_AIF(const semantics::complete_statement& stmt) branch_provider.jump_in_statements(target->name, target->symbol_range); } -void ca_processor::process_MACRO(const semantics::complete_statement& stmt) +void ca_processor::process_MACRO(const processing::resolved_statement& stmt) { register_seq_sym(stmt); listener_.start_macro_definition({}); } -void ca_processor::process_MEXIT(const semantics::complete_statement& stmt) +void ca_processor::process_MEXIT(const processing::resolved_statement& stmt) { if (!hlasm_ctx.is_in_macro()) add_diagnostic(diagnostic_op::error_E054(stmt.stmt_range_ref())); @@ -435,18 +435,18 @@ void ca_processor::process_MEXIT(const semantics::complete_statement& stmt) hlasm_ctx.leave_macro(); } -void ca_processor::process_MEND(const semantics::complete_statement& stmt) +void ca_processor::process_MEND(const processing::resolved_statement& stmt) { if (!hlasm_ctx.is_in_macro()) add_diagnostic(diagnostic_op::error_E054(stmt.stmt_range_ref())); } -void ca_processor::process_AEJECT(const semantics::complete_statement&) +void ca_processor::process_AEJECT(const processing::resolved_statement&) { // TODO } -void ca_processor::process_ASPACE(const semantics::complete_statement& stmt) +void ca_processor::process_ASPACE(const processing::resolved_statement& stmt) { // TODO (void)stmt; @@ -484,7 +484,7 @@ struct AREAD_operand_visitor final : public semantics::operand_visitor }; } // namespace -void ca_processor::process_AREAD(const semantics::complete_statement& stmt) +void ca_processor::process_AREAD(const processing::resolved_statement& stmt) { if (stmt.label_ref().type != semantics::label_si_type::VAR) { @@ -577,10 +577,10 @@ void ca_processor::process_AREAD(const semantics::complete_statement& stmt) set_symbol->access_set_symbol()->set_value(std::move(value_to_set), index); } -void ca_processor::process_empty(const semantics::complete_statement&) {} +void ca_processor::process_empty(const processing::resolved_statement&) {} template -void ca_processor::process_SET(const semantics::complete_statement& stmt) +void ca_processor::process_SET(const processing::resolved_statement& stmt) { auto [set_symbol, name, index] = get_SET_symbol(stmt); @@ -608,12 +608,12 @@ void ca_processor::process_SET(const semantics::complete_statement& stmt) } } -template void ca_processor::process_SET(const semantics::complete_statement& stmt); -template void ca_processor::process_SET(const semantics::complete_statement& stmt); -template void ca_processor::process_SET(const semantics::complete_statement& stmt); +template void ca_processor::process_SET(const processing::resolved_statement& stmt); +template void ca_processor::process_SET(const processing::resolved_statement& stmt); +template void ca_processor::process_SET(const processing::resolved_statement& stmt); template -void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt) +void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt) { register_seq_sym(stmt); @@ -636,14 +636,14 @@ void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt) } } -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); -template void ca_processor::process_GBL_LCL(const semantics::complete_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); +template void ca_processor::process_GBL_LCL(const processing::resolved_statement& stmt); -void ca_processor::process_MHELP(const semantics::complete_statement& stmt) +void ca_processor::process_MHELP(const processing::resolved_statement& stmt) { register_seq_sym(stmt); diff --git a/parser_library/src/processing/instruction_sets/ca_processor.h b/parser_library/src/processing/instruction_sets/ca_processor.h index 755cea50a..0fb7496c8 100644 --- a/parser_library/src/processing/instruction_sets/ca_processor.h +++ b/parser_library/src/processing/instruction_sets/ca_processor.h @@ -29,7 +29,7 @@ class opencode_provider; class ca_processor : public instruction_processor { using process_table_t = - std::unordered_map>; + std::unordered_map>; const process_table_t table_; processing_state_listener& listener_; @@ -48,7 +48,7 @@ class ca_processor : public instruction_processor process_table_t create_table(); - void register_seq_sym(const semantics::complete_statement& stmt); + void register_seq_sym(const processing::resolved_statement& stmt); struct SET_info { @@ -73,38 +73,38 @@ class ca_processor : public instruction_processor std::vector m_set_work; template - SET_info get_SET_symbol(const semantics::complete_statement& stmt); + SET_info get_SET_symbol(const processing::resolved_statement& stmt); bool prepare_SET_operands( - const semantics::complete_statement& stmt, std::vector& expr_values); + const processing::resolved_statement& stmt, std::vector& expr_values); template - void process_SET(const semantics::complete_statement& stmt); + void process_SET(const processing::resolved_statement& stmt); - bool prepare_GBL_LCL(const semantics::complete_statement& stmt, std::vector& info) const; + bool prepare_GBL_LCL(const processing::resolved_statement& stmt, std::vector& info) const; template - void process_GBL_LCL(const semantics::complete_statement& stmt); + void process_GBL_LCL(const processing::resolved_statement& stmt); - void process_ANOP(const semantics::complete_statement& stmt); + void process_ANOP(const processing::resolved_statement& stmt); - void process_ACTR(const semantics::complete_statement& stmt); + void process_ACTR(const processing::resolved_statement& stmt); - const semantics::seq_sym* prepare_AGO(const semantics::complete_statement& stmt); - void process_AGO(const semantics::complete_statement& stmt); + const semantics::seq_sym* prepare_AGO(const processing::resolved_statement& stmt); + void process_AGO(const processing::resolved_statement& stmt); - const semantics::seq_sym* prepare_AIF(const semantics::complete_statement& stmt); - void process_AIF(const semantics::complete_statement& stmt); + const semantics::seq_sym* prepare_AIF(const processing::resolved_statement& stmt); + void process_AIF(const processing::resolved_statement& stmt); - void process_MACRO(const semantics::complete_statement& stmt); - void process_MEXIT(const semantics::complete_statement& stmt); - void process_MEND(const semantics::complete_statement& stmt); - void process_AEJECT(const semantics::complete_statement& stmt); - void process_ASPACE(const semantics::complete_statement& stmt); - void process_AREAD(const semantics::complete_statement& stmt); + void process_MACRO(const processing::resolved_statement& stmt); + void process_MEXIT(const processing::resolved_statement& stmt); + void process_MEND(const processing::resolved_statement& stmt); + void process_AEJECT(const processing::resolved_statement& stmt); + void process_ASPACE(const processing::resolved_statement& stmt); + void process_AREAD(const processing::resolved_statement& stmt); - void process_empty(const semantics::complete_statement&); + void process_empty(const processing::resolved_statement&); - void process_MHELP(const semantics::complete_statement& stmt); + void process_MHELP(const processing::resolved_statement& stmt); }; } // namespace hlasm_plugin::parser_library::processing diff --git a/parser_library/src/processing/instruction_sets/instruction_processor.cpp b/parser_library/src/processing/instruction_sets/instruction_processor.cpp index 55a597493..b0f1b9fbd 100644 --- a/parser_library/src/processing/instruction_sets/instruction_processor.cpp +++ b/parser_library/src/processing/instruction_sets/instruction_processor.cpp @@ -20,7 +20,7 @@ namespace hlasm_plugin::parser_library::processing { void instruction_processor::register_literals( - const semantics::complete_statement& stmt, context::alignment loctr_alignment, size_t unique_id) + const processing::resolved_statement& stmt, context::alignment loctr_alignment, size_t unique_id) { if (auto literals = stmt.literals(); !literals.empty()) { diff --git a/parser_library/src/processing/instruction_sets/instruction_processor.h b/parser_library/src/processing/instruction_sets/instruction_processor.h index f1339eb83..d7d4d9e9e 100644 --- a/parser_library/src/processing/instruction_sets/instruction_processor.h +++ b/parser_library/src/processing/instruction_sets/instruction_processor.h @@ -53,7 +53,7 @@ class instruction_processor : public diagnosable_ctx {} void register_literals( - const semantics::complete_statement& stmt, context::alignment loctr_alignment, size_t unique_id); + const processing::resolved_statement& stmt, context::alignment loctr_alignment, size_t unique_id); }; } // namespace hlasm_plugin::parser_library::processing diff --git a/parser_library/src/processing/instruction_sets/low_language_processor.cpp b/parser_library/src/processing/instruction_sets/low_language_processor.cpp index 70b47b36e..24c04663e 100644 --- a/parser_library/src/processing/instruction_sets/low_language_processor.cpp +++ b/parser_library/src/processing/instruction_sets/low_language_processor.cpp @@ -37,9 +37,8 @@ low_language_processor::low_language_processor(const analyzing_context& ctx, , proc_mgr(proc_mgr) {} -rebuilt_statement low_language_processor::preprocess(std::shared_ptr statement) +rebuilt_statement low_language_processor::preprocess(std::shared_ptr stmt) { - auto stmt = std::static_pointer_cast(std::move(statement)); auto [label, ops, literals, was_model] = preprocess_inner(*stmt); rebuilt_statement result(std::move(stmt), std::move(label), std::move(ops), std::move(literals)); if (was_model) diff --git a/parser_library/src/processing/instruction_sets/macro_processor.cpp b/parser_library/src/processing/instruction_sets/macro_processor.cpp index 7079715f5..e3b11a84b 100644 --- a/parser_library/src/processing/instruction_sets/macro_processor.cpp +++ b/parser_library/src/processing/instruction_sets/macro_processor.cpp @@ -331,9 +331,9 @@ void macro_processor::get_keyword_arg(const resolved_statement& statement, std::vector& keyword_params, range op_range) const { - auto named = hlasm_ctx.get_macro_definition(statement.opcode_ref().value)->named_params().find(arg_name); - if (named == hlasm_ctx.get_macro_definition(statement.opcode_ref().value)->named_params().end() - || named->second->param_type == context::macro_param_type::POS_PAR_TYPE) + const auto& named_params = hlasm_ctx.get_macro_definition(statement.opcode_ref().value)->named_params(); + auto named = named_params.find(arg_name); + if (named == named_params.end() || named->second->param_type == context::macro_param_type::POS_PAR_TYPE) { add_diagnostic(diagnostic_op::warning_W014(op_range)); diff --git a/parser_library/src/processing/instruction_sets/postponed_statement_impl.h b/parser_library/src/processing/instruction_sets/postponed_statement_impl.h index 8a5ec84b1..e51462474 100644 --- a/parser_library/src/processing/instruction_sets/postponed_statement_impl.h +++ b/parser_library/src/processing/instruction_sets/postponed_statement_impl.h @@ -23,29 +23,14 @@ namespace hlasm_plugin::parser_library::processing { // implementation of postponed_statement interface -struct postponed_statement_impl : public context::postponed_statement, public resolved_statement +struct postponed_statement_impl : public context::postponed_statement { - postponed_statement_impl(rebuilt_statement&& stmt, context::processing_stack_t stmt_location_stack) - : stmt(std::move(stmt)) - , stmt_location_stack(std::move(stmt_location_stack)) + postponed_statement_impl(rebuilt_statement&& s, context::processing_stack_t stmt_location_stack) + : context::postponed_statement(stmt_location_stack, &stmt) + , stmt(std::move(s)) {} rebuilt_statement stmt; - context::processing_stack_t stmt_location_stack; - - const processing::resolved_statement* resolved_stmt() const override { return this; } - - const semantics::label_si& label_ref() const override { return stmt.label_ref(); } - const semantics::instruction_si& instruction_ref() const override { return stmt.instruction_ref(); } - const semantics::operands_si& operands_ref() const override { return stmt.operands_ref(); } - const semantics::remarks_si& remarks_ref() const override { return stmt.remarks_ref(); } - std::span literals() const override { return stmt.literals(); } - const range& stmt_range_ref() const override { return stmt.stmt_range_ref(); } - const op_code& opcode_ref() const override { return stmt.opcode_ref(); } - processing_format format_ref() const override { return stmt.format_ref(); } - - const context::processing_stack_t& location_stack() const override { return stmt_location_stack; } - std::span diagnostics() const override { return stmt.diagnostics(); } }; } // namespace hlasm_plugin::parser_library::processing diff --git a/parser_library/src/processing/opencode_provider.cpp b/parser_library/src/processing/opencode_provider.cpp index 4cf5e85ef..7ea1494bc 100644 --- a/parser_library/src/processing/opencode_provider.cpp +++ b/parser_library/src/processing/opencode_provider.cpp @@ -269,9 +269,13 @@ namespace { bool operands_relevant_in_lookahead(bool has_label, const processing_status& status) { static constexpr context::id_index EQU("EQU"); - return status.first.form == processing_form::ASM && status.second.value == context::id_storage::well_known::COPY - || status.first.form == processing_form::ASM && status.second.value == EQU && has_label - || status.first.form == processing_form::DAT && has_label; + using enum processing_form; + const auto& COPY = context::id_storage::well_known::COPY; + + const auto form = status.first.form; + const auto& instr = status.second.value; + + return form == ASM && instr == COPY || form == ASM && instr == EQU && has_label || form == DAT && has_label; } } // namespace diff --git a/parser_library/src/processing/statement.h b/parser_library/src/processing/statement.h index ea613b332..f2e6524e2 100644 --- a/parser_library/src/processing/statement.h +++ b/parser_library/src/processing/statement.h @@ -26,48 +26,23 @@ namespace hlasm_plugin::parser_library::processing { // statement that contains resolved operation code and also all semantic fields -struct resolved_statement : public context::hlasm_statement, public semantics::complete_statement +struct resolved_statement : public context::hlasm_statement { + virtual const semantics::label_si& label_ref() const = 0; + virtual const semantics::instruction_si& instruction_ref() const = 0; + virtual const semantics::operands_si& operands_ref() const = 0; + virtual const semantics::remarks_si& remarks_ref() const = 0; + virtual std::span literals() const = 0; + virtual const op_code& opcode_ref() const = 0; virtual processing_format format_ref() const = 0; - position statement_position() const override { return stmt_range_ref().start; } - resolved_statement() : context::hlasm_statement(context::statement_kind::RESOLVED) {} -}; - -struct resolved_statement_impl final : public resolved_statement -{ - resolved_statement_impl(std::shared_ptr base_stmt, processing_status status) - : base_stmt(std::move(base_stmt)) - , status(std::move(status)) - {} - resolved_statement_impl(std::shared_ptr base_stmt, - processing_status status, - std::vector&& diags) - : base_stmt(std::move(base_stmt)) - , status(std::move(status)) - , statement_diagnostics(std::make_move_iterator(diags.begin()), std::make_move_iterator(diags.end())) - {} - std::shared_ptr base_stmt; - processing_status status; - std::vector statement_diagnostics; - - const semantics::label_si& label_ref() const override { return base_stmt->label_ref(); } - const semantics::instruction_si& instruction_ref() const override { return base_stmt->instruction_ref(); } - const semantics::operands_si& operands_ref() const override { return base_stmt->operands_ref(); } - const semantics::remarks_si& remarks_ref() const override { return base_stmt->remarks_ref(); } - const range& stmt_range_ref() const override { return base_stmt->stmt_range_ref(); } - std::span literals() const override { return base_stmt->literals(); } - const op_code& opcode_ref() const override { return status.second; } - processing_format format_ref() const override { return status.first; } - std::span diagnostics() const override - { - return { statement_diagnostics.data(), statement_diagnostics.data() + statement_diagnostics.size() }; - } +protected: + ~resolved_statement() = default; }; // statement used for preprocessing of resolved statements @@ -88,6 +63,8 @@ struct rebuilt_statement final : public resolved_statement std::optional rebuilt_operands; std::optional> rebuilt_literals; + const range& stmt_range_ref() const override { return base_stmt->stmt_range_ref(); } + const semantics::label_si& label_ref() const override { return rebuilt_label ? *rebuilt_label : base_stmt->label_ref(); @@ -102,7 +79,6 @@ struct rebuilt_statement final : public resolved_statement return rebuilt_literals ? *rebuilt_literals : base_stmt->literals(); } const semantics::remarks_si& remarks_ref() const override { return base_stmt->remarks_ref(); } - const range& stmt_range_ref() const override { return base_stmt->stmt_range_ref(); } const op_code& opcode_ref() const override { return base_stmt->opcode_ref(); } processing_format format_ref() const override { return base_stmt->format_ref(); } diff --git a/parser_library/src/processing/statement_analyzers/hit_count_analyzer.cpp b/parser_library/src/processing/statement_analyzers/hit_count_analyzer.cpp index 55327e696..9c266c722 100644 --- a/parser_library/src/processing/statement_analyzers/hit_count_analyzer.cpp +++ b/parser_library/src/processing/statement_analyzers/hit_count_analyzer.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "context/hlasm_context.h" @@ -29,25 +30,28 @@ hit_count_analyzer::hit_count_analyzer(context::hlasm_context& ctx) {} namespace { -constexpr auto get_core_stmt = [](const context::hlasm_statement* stmt) -> const semantics::core_statement* { +constexpr auto get_core_stmt = [](const context::hlasm_statement* stmt) + -> std::optional> { if (!stmt) - return nullptr; + return std::nullopt; if (stmt->kind == context::statement_kind::RESOLVED) - return stmt->access_resolved(); + { + const auto& res = stmt->access_resolved(); + return std::tie(res->stmt_range_ref(), res->instruction_ref()); + } else if (stmt->kind == context::statement_kind::DEFERRED) - return stmt->access_deferred(); + { + const auto& def = stmt->access_deferred(); + return std::tie(def->stmt_range, def->instruction); + } - return nullptr; + return std::nullopt; }; -std::optional get_stmt_lines_range(const semantics::core_statement& statement, - statement_provider_kind prov_kind, - processing_kind proc_kind, - const context::hlasm_context& ctx) +std::optional get_stmt_lines_range( + const range& r, statement_provider_kind prov_kind, processing_kind proc_kind, const context::hlasm_context& ctx) { - const auto& r = statement.stmt_range_ref(); - if (proc_kind != processing_kind::LOOKAHEAD && r.start == r.end) return std::nullopt; @@ -72,10 +76,10 @@ hit_count_entry& hit_count_analyzer::get_hc_entry_reference(const utils::resourc return m_hit_count_map.try_emplace(rl).first->second; } -hit_count_analyzer::statement_type hit_count_analyzer::get_stmt_type(const semantics::core_statement& statement) +hit_count_analyzer::statement_type hit_count_analyzer::get_stmt_type(const semantics::instruction_si& instr) { statement_type cur_stmt_type = m_next_stmt_type; - if (const auto instr_id = std::get_if(&statement.instruction_ref().value); instr_id) + if (const auto instr_id = std::get_if(&instr.value); instr_id) { if (*instr_id == context::id_storage::well_known::MACRO) cur_stmt_type = statement_type::MACRO_INIT; @@ -121,13 +125,13 @@ bool hit_count_analyzer::analyze( if (!core_stmt_ptr) return false; - const auto& core_stmt = *core_stmt_ptr; + const auto& [rng, instr] = *core_stmt_ptr; - auto stmt_type = get_stmt_type(core_stmt); + auto stmt_type = get_stmt_type(instr); if (stmt_type != statement_type::REGULAR && stmt_type != statement_type::MACRO_BODY) return false; - auto stmt_lines_range = get_stmt_lines_range(core_stmt, prov_kind, proc_kind, m_ctx); + auto stmt_lines_range = get_stmt_lines_range(rng, prov_kind, proc_kind, m_ctx); if (!stmt_lines_range) return false; diff --git a/parser_library/src/processing/statement_analyzers/hit_count_analyzer.h b/parser_library/src/processing/statement_analyzers/hit_count_analyzer.h index 25117c0d4..21135481a 100644 --- a/parser_library/src/processing/statement_analyzers/hit_count_analyzer.h +++ b/parser_library/src/processing/statement_analyzers/hit_count_analyzer.h @@ -33,7 +33,7 @@ class hlasm_context; } // namespace context namespace semantics { -struct core_statement; +struct instruction_si; } // namespace semantics } // namespace hlasm_plugin::parser_library @@ -186,7 +186,7 @@ class hit_count_analyzer final : public statement_analyzer const utils::resource::resource_location& get_current_stmt_rl(processing_kind proc_kind) const; hit_count_entry& get_hc_entry_reference(const utils::resource::resource_location& rl); - statement_type get_stmt_type(const semantics::core_statement& statement); + statement_type get_stmt_type(const semantics::instruction_si& instr); }; } // namespace hlasm_plugin::parser_library::processing diff --git a/parser_library/src/processing/statement_analyzers/lsp_analyzer.cpp b/parser_library/src/processing/statement_analyzers/lsp_analyzer.cpp index 1ad4741c3..dda57efdd 100644 --- a/parser_library/src/processing/statement_analyzers/lsp_analyzer.cpp +++ b/parser_library/src/processing/statement_analyzers/lsp_analyzer.cpp @@ -268,17 +268,17 @@ void lsp_analyzer::collect_occurrences( if (auto def_stmt = statement.access_deferred()) { - if (def_stmt->instruction_ref().type != semantics::instruction_si_type::EMPTY) + if (def_stmt->instruction.type != semantics::instruction_si_type::EMPTY) { - const auto& r = def_stmt->stmt_range_ref(); + const auto& r = def_stmt->stmt_range; collect_endline(r, ci); collect_usings(r, ci); // no section collection for deferred statements } - collect_occurrence(def_stmt->label_ref(), collector); - collect_occurrence(def_stmt->instruction_ref(), collector, nullptr); - collect_occurrence(def_stmt->deferred_ref(), collector); + collect_occurrence(def_stmt->label, collector); + collect_occurrence(def_stmt->instruction, collector, nullptr); + collect_occurrence(def_stmt->deferred_operands, collector); } else if (auto res_stmt = statement.access_resolved()) { @@ -625,7 +625,7 @@ void lsp_analyzer::collect_branch_info( if (!stmt) continue; - const auto* rs = stmt->resolved_stmt(); + const auto* rs = stmt->resolved_stmt; const auto& opcode = rs->opcode_ref(); if (opcode.type != context::instruction_type::MACH) continue; @@ -635,7 +635,7 @@ void lsp_analyzer::collect_branch_info( if (!transfer.has_value()) continue; - const auto loc = get_opencode_stackframe(stmt->location_stack()); + const auto loc = get_opencode_stackframe(stmt->location_stack); if (loc.empty() && *loc.frame().resource_loc != opencode_loc) continue; diff --git a/parser_library/src/processing/statement_processors/lookahead_processor.cpp b/parser_library/src/processing/statement_processors/lookahead_processor.cpp index d45a8c153..1b318d02d 100644 --- a/parser_library/src/processing/statement_processors/lookahead_processor.cpp +++ b/parser_library/src/processing/statement_processors/lookahead_processor.cpp @@ -64,7 +64,7 @@ void lookahead_processor::process_statement(context::shared_stmt_ptr statement) if (macro_nest_ == 0) { - find_seq(*resolved); + find_seq(resolved->label_ref()); find_ord(*resolved); } if (opcode == context::id_storage::well_known::MACRO) @@ -295,19 +295,19 @@ void lookahead_processor::assign_cxd_attributes(context::id_index symbol_name, c register_attr_ref(symbol_name, context::symbol_attributes(context::symbol_origin::ASM, 'A'_ebcdic, 4)); } -void lookahead_processor::find_seq(const semantics::core_statement& statement) +void lookahead_processor::find_seq(const semantics::label_si& label) { - if (statement.label_ref().type == semantics::label_si_type::SEQ) - { - const auto& symbol = std::get(statement.label_ref().value); + if (label.type != semantics::label_si_type::SEQ) + return; - branch_provider_.register_sequence_symbol(symbol.name, symbol.symbol_range); + const auto& symbol = std::get(label.value); - if (symbol.name == target_) - { - finished_flag_ = true; - result_ = lookahead_processing_result(symbol.name, symbol.symbol_range); - } + branch_provider_.register_sequence_symbol(symbol.name, symbol.symbol_range); + + if (symbol.name == target_) + { + finished_flag_ = true; + result_ = lookahead_processing_result(symbol.name, symbol.symbol_range); } } diff --git a/parser_library/src/processing/statement_processors/lookahead_processor.h b/parser_library/src/processing/statement_processors/lookahead_processor.h index bf76dcfc6..695ec31df 100644 --- a/parser_library/src/processing/statement_processors/lookahead_processor.h +++ b/parser_library/src/processing/statement_processors/lookahead_processor.h @@ -76,7 +76,7 @@ class lookahead_processor final : public statement_processor void assign_machine_attributes(context::id_index symbol_name, const resolved_statement& statement); void assign_assembler_attributes(context::id_index symbol_name, const resolved_statement& statement); - void find_seq(const semantics::core_statement& statement); + void find_seq(const semantics::label_si& label); void find_ord(const resolved_statement& statement); void register_attr_ref(context::id_index name, context::symbol_attributes attributes); diff --git a/parser_library/src/processing/statement_processors/macrodef_processor.cpp b/parser_library/src/processing/statement_processors/macrodef_processor.cpp index 5e8fd57b4..87ea630d1 100644 --- a/parser_library/src/processing/statement_processors/macrodef_processor.cpp +++ b/parser_library/src/processing/statement_processors/macrodef_processor.cpp @@ -164,8 +164,8 @@ bool macrodef_processor::process_statement(const context::hlasm_statement& state if (!res_stmt || res_stmt->opcode_ref().value != context::id_storage::well_known::MACRO) { - range r = res_stmt ? res_stmt->stmt_range_ref() : range(statement.statement_position()); - add_diagnostic(diagnostic_op::error_E059(start_.external_name.to_string_view(), r)); + add_diagnostic( + diagnostic_op::error_E059(start_.external_name.to_string_view(), statement.stmt_range_ref())); result_.invalid = true; finished_flag_ = true; return false; @@ -177,8 +177,7 @@ bool macrodef_processor::process_statement(const context::hlasm_statement& state { if (!res_stmt) { - range r = res_stmt ? res_stmt->stmt_range_ref() : range(statement.statement_position()); - add_diagnostic(diagnostic_op::error_E071(r)); + add_diagnostic(diagnostic_op::error_E071(statement.stmt_range_ref())); result_.invalid = true; return false; } @@ -203,7 +202,7 @@ bool macrodef_processor::process_statement(const context::hlasm_statement& state } else if (auto def_stmt = statement.access_deferred()) { - process_sequence_symbol(def_stmt->label_ref()); + process_sequence_symbol(def_stmt->label); } } return false; @@ -384,22 +383,41 @@ bool macrodef_processor::process_MEND() return false; } +struct empty_statement_t final : public resolved_statement +{ + explicit empty_statement_t(range r) + : label(r) + , instruction(r) + , operands(r, {}) + , remarks(r, {}) + {} + + static const processing_status status; + + semantics::label_si label; + semantics::instruction_si instruction; + semantics::operands_si operands; + semantics::remarks_si remarks; + + const range& stmt_range_ref() const override { return instruction.field_range; } + const semantics::label_si& label_ref() const override { return label; } + const semantics::instruction_si& instruction_ref() const override { return instruction; } + const semantics::operands_si& operands_ref() const override { return operands; } + const semantics::remarks_si& remarks_ref() const override { return remarks; } + std::span literals() const override { return {}; } + const op_code& opcode_ref() const override { return status.second; } + processing_format format_ref() const override { return status.first; } + std::span diagnostics() const override { return {}; } +}; + +const processing_status empty_statement_t::status( + processing_format(processing_kind::ORDINARY, processing_form::CA, operand_occurrence::ABSENT), + op_code(context::id_storage::well_known::ANOP, context::instruction_type::CA, nullptr)); + bool macrodef_processor::process_COPY(const resolved_statement& statement) { // substitute copy for anop to not be processed again - - auto empty_sem = std::make_shared(statement.stmt_range_ref(), - semantics::label_si(statement.stmt_range_ref()), - semantics::instruction_si(statement.stmt_range_ref()), - semantics::operands_si(statement.stmt_range_ref(), {}), - semantics::remarks_si(statement.stmt_range_ref(), {}), - std::vector()); - - auto empty = std::make_unique(std::move(empty_sem), - processing_status(processing_format(processing_kind::ORDINARY, processing_form::CA, operand_occurrence::ABSENT), - op_code(context::id_storage::well_known::ANOP, context::instruction_type::CA, nullptr))); - - result_.definition.push_back(std::move(empty)); + result_.definition.push_back(std::make_shared(statement.stmt_range_ref())); add_correct_copy_nest(); if (auto extract = asm_processor::extract_copy_id(statement, nullptr); extract.has_value()) diff --git a/parser_library/src/processing/statement_processors/ordinary_processor.cpp b/parser_library/src/processing/statement_processors/ordinary_processor.cpp index 0f5986316..638744167 100644 --- a/parser_library/src/processing/statement_processors/ordinary_processor.cpp +++ b/parser_library/src/processing/statement_processors/ordinary_processor.cpp @@ -489,8 +489,8 @@ void ordinary_processor::check_postponed_statements( context::ordinary_assembly_dependency_solver dep_solver(hlasm_ctx.ord_ctx, dep_ctx, lib_info); - const auto* rs = stmt->resolved_stmt(); - diagnostic_collector collector(this, stmt->location_stack()); + const auto* rs = stmt->resolved_stmt; + diagnostic_collector collector(this, stmt->location_stack); operand_vector.clear(); diff --git a/parser_library/src/processing/statement_providers/members_statement_provider.cpp b/parser_library/src/processing/statement_providers/members_statement_provider.cpp index 85cdc73a6..44eeacfb7 100644 --- a/parser_library/src/processing/statement_providers/members_statement_provider.cpp +++ b/parser_library/src/processing/statement_providers/members_statement_provider.cpp @@ -63,7 +63,7 @@ context::shared_stmt_ptr members_statement_provider::get_next(const statement_pr break; case context::statement_kind::DEFERRED: { stmt = cache->get_base(); - const auto& current_instr = stmt->access_deferred()->instruction_ref(); + const auto& current_instr = stmt->access_deferred()->instruction; if (!resolved_instruction.has_value()) resolved_instruction.emplace(processor.resolve_instruction(current_instr)); auto proc_status_o = processor.get_processing_status(*resolved_instruction, current_instr.field_range); @@ -101,7 +101,7 @@ const semantics::instruction_si* members_statement_provider::retrieve_instructio case context::statement_kind::RESOLVED: return &cache.get_base()->access_resolved()->instruction_ref(); case context::statement_kind::DEFERRED: - return &cache.get_base()->access_deferred()->instruction_ref(); + return &cache.get_base()->access_deferred()->instruction; case context::statement_kind::ERROR: return nullptr; default: @@ -109,39 +109,82 @@ const semantics::instruction_si* members_statement_provider::retrieve_instructio } } -void members_statement_provider::fill_cache(context::statement_cache& cache, +// structure holding deferred statement that is now complete +struct statement_si_defer_done final +{ + statement_si_defer_done(std::shared_ptr deferred_stmt, + semantics::operands_si operands, + semantics::remarks_si remarks, + std::vector collected_literals) + : deferred_stmt(std::move(deferred_stmt)) + , operands(std::move(operands)) + , remarks(std::move(remarks)) + , collected_literals(std::move(collected_literals)) + {} + + std::shared_ptr deferred_stmt; + + semantics::operands_si operands; + semantics::remarks_si remarks; + std::vector collected_literals; +}; + +const context::statement_cache::cached_statement_t& members_statement_provider::fill_cache( + context::statement_cache& cache, std::shared_ptr def_stmt, const processing_status& status) { context::statement_cache::cached_statement_t reparsed_stmt { {}, filter_cached_diagnostics(*def_stmt) }; - const auto& def_s = def_stmt->deferred_ref(); + const auto& def_ops = def_stmt->deferred_operands; if (status.first.occurrence == operand_occurrence::ABSENT || status.first.form == processing_form::UNKNOWN || status.first.form == processing_form::IGNORED) { - semantics::operands_si op(def_s.field_range, semantics::operand_list()); - semantics::remarks_si rem(def_s.field_range, {}); + semantics::operands_si op(def_ops.field_range, semantics::operand_list()); + semantics::remarks_si rem(def_ops.field_range, {}); - reparsed_stmt.stmt = std::make_shared( + reparsed_stmt.stmt = std::make_shared( std::move(def_stmt), std::move(op), std::move(rem), std::vector()); } else { diagnostic_consumer_transform diag_consumer( [&reparsed_stmt](diagnostic_op diag) { reparsed_stmt.diags.push_back(std::move(diag)); }); - auto [op, rem, lits] = m_parser.parse_operand_field(def_s.value, + auto [op, rem, lits] = m_parser.parse_operand_field(def_ops.value, false, - semantics::range_provider(def_s.field_range, semantics::adjusting_state::NONE), - def_s.logical_column, + semantics::range_provider(def_ops.field_range, semantics::adjusting_state::NONE), + def_ops.logical_column, status, diag_consumer); - reparsed_stmt.stmt = std::make_shared( + reparsed_stmt.stmt = std::make_shared( std::move(def_stmt), std::move(op), std::move(rem), std::move(lits)); } - cache.insert(processing_status_cache_key(status), std::move(reparsed_stmt)); + return cache.insert(processing_status_cache_key(status), std::move(reparsed_stmt)); } +struct deferred_statement_adapter final : public resolved_statement +{ + deferred_statement_adapter(std::shared_ptr base_stmt, processing_status status) + : base_stmt(std::move(base_stmt)) + , status(std::move(status)) + {} + + std::shared_ptr base_stmt; + processing_status status; + + const range& stmt_range_ref() const override { return base_stmt->deferred_stmt->stmt_range; } + const semantics::label_si& label_ref() const override { return base_stmt->deferred_stmt->label; } + const semantics::instruction_si& instruction_ref() const override { return base_stmt->deferred_stmt->instruction; } + const semantics::operands_si& operands_ref() const override { return base_stmt->operands; } + const semantics::remarks_si& remarks_ref() const override { return base_stmt->remarks; } + std::span literals() const override { return base_stmt->collected_literals; } + const op_code& opcode_ref() const override { return status.second; } + processing_format format_ref() const override { return status.first; } + std::span diagnostics() const override { return {}; } +}; + + context::shared_stmt_ptr members_statement_provider::preprocess_deferred(const statement_processor& processor, context::statement_cache& cache, processing_status status, @@ -151,10 +194,9 @@ context::shared_stmt_ptr members_statement_provider::preprocess_deferred(const s processing_status_cache_key key(status); - if (!cache.contains(key)) - fill_cache(cache, { std::move(base_stmt), &def_stmt }, status); - - const auto& cache_item = cache.get(key); + const auto* cache_item = cache.get(key); + if (!cache_item) + cache_item = &fill_cache(cache, { std::move(base_stmt), &def_stmt }, status); if (processor.kind != processing_kind::LOOKAHEAD) { @@ -162,7 +204,7 @@ context::shared_stmt_ptr members_statement_provider::preprocess_deferred(const s m_diagnoser.add_diagnostic(diag); } - return std::make_shared(cache_item->stmt, status); + return std::make_shared(cache_item->stmt, status); } } // namespace hlasm_plugin::parser_library::processing diff --git a/parser_library/src/processing/statement_providers/members_statement_provider.h b/parser_library/src/processing/statement_providers/members_statement_provider.h index 25e9f87bf..66474559b 100644 --- a/parser_library/src/processing/statement_providers/members_statement_provider.h +++ b/parser_library/src/processing/statement_providers/members_statement_provider.h @@ -69,7 +69,7 @@ class members_statement_provider : public statement_provider private: const semantics::instruction_si* retrieve_instruction(const context::statement_cache& cache) const; - void fill_cache(context::statement_cache& cache, + const context::statement_cache::cached_statement_t& fill_cache(context::statement_cache& cache, std::shared_ptr def_stmt, const processing_status& status); diff --git a/parser_library/src/processing/statement_providers/statement_provider.cpp b/parser_library/src/processing/statement_providers/statement_provider.cpp index 7ca1ae4c1..0d032365e 100644 --- a/parser_library/src/processing/statement_providers/statement_provider.cpp +++ b/parser_library/src/processing/statement_providers/statement_provider.cpp @@ -50,7 +50,7 @@ bool statement_provider::try_trigger_attribute_lookahead(const context::hlasm_st if (auto def_stmt = statement.access_deferred()) { - label = &def_stmt->label_ref(); + label = &def_stmt->label; } else if (auto res_stmt = statement.access_resolved()) { diff --git a/parser_library/src/semantics/collector.cpp b/parser_library/src/semantics/collector.cpp index 1e7552cd6..c7e8f6a1f 100644 --- a/parser_library/src/semantics/collector.cpp +++ b/parser_library/src/semantics/collector.cpp @@ -191,6 +191,51 @@ void collector::append_operand_field(collector&& c) lit_.insert(lit_.end(), std::make_move_iterator(c.lit_.begin()), std::make_move_iterator(c.lit_.end())); } +// struct holding full semantic information (si) about whole instruction statement, whole logical line +struct statement_si final : public processing::resolved_statement +{ + statement_si(range stmt_range, + label_si label, + instruction_si instruction, + operands_si operands, + remarks_si remarks, + std::vector&& literals, + processing::processing_status status, + std::vector&& diags) + : label(std::move(label)) + , instruction(std::move(instruction)) + , operands(std::move(operands)) + , remarks(std::move(remarks)) + , collected_literals(std::make_move_iterator(literals.begin()), std::make_move_iterator(literals.end())) + , status(std::move(status)) + , statement_diagnostics(std::make_move_iterator(diags.begin()), std::make_move_iterator(diags.end())) + , stmt_range(stmt_range) + {} + + label_si label; + instruction_si instruction; + operands_si operands; + remarks_si remarks; + std::vector collected_literals; + processing::processing_status status; + std::vector statement_diagnostics; + range stmt_range; + + const range& stmt_range_ref() const override { return stmt_range; } + const label_si& label_ref() const override { return label; } + const instruction_si& instruction_ref() const override { return instruction; } + const operands_si& operands_ref() const override { return operands; } + std::span literals() const override { return collected_literals; } + const remarks_si& remarks_ref() const override { return remarks; } + + const processing::op_code& opcode_ref() const override { return status.second; } + processing::processing_format format_ref() const override { return status.first; } + std::span diagnostics() const override + { + return { statement_diagnostics.data(), statement_diagnostics.data() + statement_diagnostics.size() }; + } +}; + context::shared_stmt_ptr collector::extract_statement(processing::processing_status status, range& statement_range) { if (!lbl_) @@ -209,7 +254,7 @@ context::shared_stmt_ptr collector::extract_statement(processing::processing_sta assert(lit_.empty()); if (!def_) def_.emplace(instr_->field_range, 0, "", std::vector()); - return std::make_shared(union_range(lbl_->field_range, def_->field_range), + return std::make_shared(union_range(lbl_->field_range, def_->field_range), std::move(*lbl_), std::move(*instr_), std::move(*def_), @@ -228,11 +273,14 @@ context::shared_stmt_ptr collector::extract_statement(processing::processing_sta op_->value[i] = std::make_unique(instr_.value().field_range); } - statement_range = union_range(lbl_->field_range, op_->field_range); - auto stmt_si = std::make_shared( - statement_range, std::move(*lbl_), std::move(*instr_), std::move(*op_), std::move(*rem_), std::move(lit_)); - return std::make_shared( - std::move(stmt_si), std::move(status), std::move(statement_diagnostics.diags)); + return std::make_shared(union_range(lbl_->field_range, op_->field_range), + std::move(*lbl_), + std::move(*instr_), + std::move(*op_), + std::move(*rem_), + std::move(lit_), + std::move(status), + std::move(statement_diagnostics.diags)); } } diff --git a/parser_library/src/semantics/statement.h b/parser_library/src/semantics/statement.h index caab1a23f..ac004e0ac 100644 --- a/parser_library/src/semantics/statement.h +++ b/parser_library/src/semantics/statement.h @@ -31,141 +31,45 @@ namespace hlasm_plugin::parser_library::semantics { -// structure representing core fields of statement -struct core_statement -{ - virtual const range& stmt_range_ref() const = 0; - virtual const label_si& label_ref() const = 0; - virtual const instruction_si& instruction_ref() const = 0; - - virtual ~core_statement() = default; -}; - -// statement with all fields -struct complete_statement : public core_statement -{ - virtual const operands_si& operands_ref() const = 0; - virtual const remarks_si& remarks_ref() const = 0; - virtual std::span literals() const = 0; -}; - -// statement with deferred operand and remark field -struct deferred_statement : public core_statement, public context::hlasm_statement -{ - virtual const deferred_operands_si& deferred_ref() const = 0; - - position statement_position() const override { return stmt_range_ref().start; } - - virtual std::span diagnostics_without_operands() const = 0; - -protected: - deferred_statement() - : context::hlasm_statement(context::statement_kind::DEFERRED) - {} -}; - // implementation of deferred statement // struct holding deferred semantic information (si) about whole instruction statement, whole logical line -struct statement_si_deferred final : public deferred_statement +struct deferred_statement final : public context::hlasm_statement { - statement_si_deferred(range stmt_range, + deferred_statement(range stmt_range, label_si label, instruction_si instruction, deferred_operands_si deferred_operands, std::vector&& diags, size_t operand_diags_start_index) - : stmt_range(std::move(stmt_range)) + : context::hlasm_statement(context::statement_kind::DEFERRED) , label(std::move(label)) , instruction(std::move(instruction)) , deferred_operands(std::move(deferred_operands)) , statement_diagnostics(std::make_move_iterator(diags.begin()), std::make_move_iterator(diags.end())) , operand_diags_start_index(operand_diags_start_index) + , stmt_range(stmt_range) {} - range stmt_range; - label_si label; instruction_si instruction; deferred_operands_si deferred_operands; std::vector statement_diagnostics; size_t operand_diags_start_index; + range stmt_range; - const label_si& label_ref() const override { return label; } - const instruction_si& instruction_ref() const override { return instruction; } - const deferred_operands_si& deferred_ref() const override { return deferred_operands; } const range& stmt_range_ref() const override { return stmt_range; } std::span diagnostics() const override { return { statement_diagnostics.data(), statement_diagnostics.data() + statement_diagnostics.size() }; } - std::span diagnostics_without_operands() const override + std::span diagnostics_without_operands() const { return { statement_diagnostics.data(), statement_diagnostics.data() + operand_diags_start_index }; } }; -// struct holding full semantic information (si) about whole instruction statement, whole logical line -struct statement_si final : public complete_statement -{ - statement_si(range stmt_range, - label_si label, - instruction_si instruction, - operands_si operands, - remarks_si remarks, - std::vector collected_literals) - : stmt_range(std::move(stmt_range)) - , label(std::move(label)) - , instruction(std::move(instruction)) - , operands(std::move(operands)) - , remarks(std::move(remarks)) - , collected_literals(std::move(collected_literals)) - {} - - range stmt_range; - - label_si label; - instruction_si instruction; - operands_si operands; - remarks_si remarks; - std::vector collected_literals; - - const label_si& label_ref() const override { return label; } - const instruction_si& instruction_ref() const override { return instruction; } - const operands_si& operands_ref() const override { return operands; } - std::span literals() const override { return collected_literals; } - const remarks_si& remarks_ref() const override { return remarks; } - const range& stmt_range_ref() const override { return stmt_range; } -}; - -// structure holding deferred statement that is now complete -struct statement_si_defer_done final : public complete_statement -{ - statement_si_defer_done(std::shared_ptr deferred_stmt, - operands_si operands, - remarks_si remarks, - std::vector collected_literals) - : deferred_stmt(std::move(deferred_stmt)) - , operands(std::move(operands)) - , remarks(std::move(remarks)) - , collected_literals(std::move(collected_literals)) - {} - - std::shared_ptr deferred_stmt; - - operands_si operands; - remarks_si remarks; - std::vector collected_literals; - - const label_si& label_ref() const override { return deferred_stmt->label_ref(); } - const instruction_si& instruction_ref() const override { return deferred_stmt->instruction_ref(); } - const operands_si& operands_ref() const override { return operands; } - std::span literals() const override { return collected_literals; } - const remarks_si& remarks_ref() const override { return remarks; } - const range& stmt_range_ref() const override { return deferred_stmt->stmt_range_ref(); } -}; - struct preproc_details { struct name_range