Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Instruction operand checking utilizes USING map #242

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
18e0789
propage active using set
slavek-kucera Mar 9, 2022
725e0fb
new diags
slavek-kucera Mar 10, 2022
a18cb37
diagnose obivous label issues
slavek-kucera Mar 10, 2022
fcebe89
postpone checking
slavek-kucera Mar 10, 2022
5c6c8de
postpone all checkings
slavek-kucera Mar 10, 2022
d022fdf
PROCESS operand validation issue
slavek-kucera Mar 11, 2022
22800df
tests to pass
slavek-kucera Mar 11, 2022
675a62f
move checker
slavek-kucera Mar 11, 2022
abffd9f
split data_attr for literal
slavek-kucera Mar 11, 2022
9abbe4e
tests to pass
slavek-kucera Mar 11, 2022
4f6393b
WIP
slavek-kucera Mar 11, 2022
8f7c973
Utilize using info in data_def validation
slavek-kucera Mar 16, 2022
adac5e1
DC S-type support
slavek-kucera Mar 14, 2022
198e794
new messages
slavek-kucera Mar 16, 2022
5e2e98e
enhance checking for mach instr
slavek-kucera Mar 16, 2022
0e3271f
more tests
slavek-kucera Mar 14, 2022
1bd5d5b
fix opsyn behavior
slavek-kucera Mar 15, 2022
953584c
tests to pass
slavek-kucera Mar 15, 2022
4ffb600
failed asserts and using map selection fix
slavek-kucera Mar 16, 2022
671fbba
random stuff
slavek-kucera Mar 17, 2022
316b8a7
update changelog
slavek-kucera Mar 17, 2022
c42fedc
fix wrong instruction formats
slavek-kucera Mar 17, 2022
cc920d2
data definition length checking is instruction dependent
slavek-kucera Mar 17, 2022
cf99778
DB2 preprocessor quick fix
slavek-kucera Mar 17, 2022
2c4600e
clang format
slavek-kucera Mar 18, 2022
0b27b45
using map dropped on missing symbol
slavek-kucera Mar 18, 2022
d8620e3
code smells
slavek-kucera Mar 18, 2022
ff0342e
refactoring
slavek-kucera Mar 18, 2022
9cfb1a1
loctr issue quick fix
slavek-kucera Mar 18, 2022
78ba4ee
...
slavek-kucera Mar 21, 2022
082e89f
...
slavek-kucera Mar 21, 2022
b53b696
crash on invalid nominal value type
slavek-kucera Mar 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#### Added
- USING and DROP support
- SYSSTMT support
- Instruction operand checking utilizes USING map

#### Fixed
- Behavior of currently supported subscripted system variables corrected
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/checking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ target_sources(parser_library PRIVATE
instruction_checker.cpp
instruction_checker.h
operand.h
using_label_checker.cpp
using_label_checker.h
)

add_subdirectory(data_definition)
2 changes: 1 addition & 1 deletion parser_library/src/checking/asm_instr_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ bool assembler_instruction::check_optable_operands(const std::vector<std::unique

bool assembler_instruction::check_typecheck_operands(const std::vector<std::unique_ptr<asm_operand>>& input,
std::string_view instr_name,
const std::string,
std::string_view,
const diagnostic_collector& add_diagnostic) const
{
const static std::vector<std::string_view> typecheck_operands = {
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/checking/asm_instr_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class assembler_instruction

bool check_typecheck_operands(const std::vector<std::unique_ptr<asm_operand>>& input,
std::string_view instr_name,
const std::string op_name,
std::string_view op_name,
const diagnostic_collector& add_diagnostic) const;

// process instruction functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct data_def_address
data_def_field<int32_t> base;
data_def_field<int32_t> displacement;
bool ignored = false;
range total;
};

using expr_or_address = std::variant<data_def_expr, data_def_address>;
Expand Down
35 changes: 35 additions & 0 deletions parser_library/src/checking/data_definition/data_def_type_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "data_def_type_base.h"

#include <optional>

#include "checking/instr_operand.h"
#include "data_def_types.h"

Expand Down Expand Up @@ -258,6 +260,28 @@ bool data_def_type::check_length(const data_def_length_t& length, const diagnost
}
}

namespace {
struct
{
std::optional<range> operator()(const data_def_expr& e) const
{
if (e.ignored)
return std::nullopt;
if (e.ex_kind != expr_type::ABS)
return e.rng;
return std::nullopt;
}
std::optional<range> operator()(const data_def_address& a) const
{
if (a.ignored)
return std::nullopt;
if (!a.displacement.present || !a.base.present)
return a.total;
return std::nullopt;
}
} const abs_or_addr;
} // namespace

bool data_def_type::check_nominal_type(
const data_definition_operand& op, const diagnostic_collector& add_diagnostic) const
{
Expand Down Expand Up @@ -294,6 +318,17 @@ bool data_def_type::check_nominal_type(
add_diagnostic(diagnostic_op::error_D017(op.operand_range, type_str));
return false;
}
for (const auto& p : std::get<nominal_value_expressions>(op.nominal_value.value))
{
if (auto range_o = std::visit(abs_or_addr, p); range_o)
{
add_diagnostic(diagnostic_op::error_D033(*range_o));
ret = false;
}
}
if (!ret)
return false;

break;
default:
assert(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class data_definition_operand;
enum class data_instr_type
{
DC,
DS
DS,
};

// Modifier spec specifies allowed values for modifiers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// This file contains implementation of the data_def_type for
// these types: B, C, G, X

#include <concepts>

#include "checking/checker_helper.h"
#include "data_def_types.h"

Expand Down Expand Up @@ -51,7 +53,8 @@ uint32_t get_X_B_length_attr(const std::string& s, uint64_t frac)
}

// Checks comma separated values. is_valid_digit specifies whether the char is valid character of value.
bool check_comma_separated(const std::string nom, std::function<bool(char c)> is_valid_digit)
template</* std::predicate<char> */ typename F>
bool check_comma_separated(const std::string& nom, F is_valid_digit)
{
bool last_valid = false;
for (char c : nom)
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/checking/instr_operand.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ struct parameter

constexpr bool is_empty() const { return (!is_signed && type == machine_operand_type::NONE && size == 0); }

bool operator==(const parameter&) const = default;

std::string to_string() const;
};

Expand Down
57 changes: 57 additions & 0 deletions parser_library/src/checking/using_label_checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*/

#include "using_label_checker.h"

#include "context/ordinary_assembly/section.h"

namespace hlasm_plugin::parser_library::checking {

void using_label_checker::add_diagnostic(diagnostic_op) const {}

void using_label_checker::visit(const expressions::mach_expr_constant&) {}
void using_label_checker::visit(const expressions::mach_expr_data_attr& attr)
{
if (!attr.value || !attr.qualifier)
return;
auto symbol = solver.get_symbol(attr.value);
if (symbol == nullptr || symbol->kind() != context::symbol_value_kind::RELOC)
return;
const auto& reloc = symbol->value().get_reloc();
if (!reloc.is_simple())
return;
const auto* section = reloc.bases().front().first.owner;
if (!solver.using_active(attr.qualifier, section))
diags.add_diagnostic(diagnostic_op::error_ME005(*attr.qualifier, *section->name, attr.get_range()));
}
void using_label_checker::visit(const expressions::mach_expr_data_attr_literal& attr) {}
void using_label_checker::visit(const expressions::mach_expr_symbol& expr)
{
if (!expr.qualifier)
return;
auto value = expr.evaluate(solver, *this);
if (value.value_kind() != context::symbol_value_kind::RELOC)
return;
const auto& reloc = value.get_reloc();
if (!reloc.is_simple())
return;
const auto* section = reloc.bases().front().first.owner;
if (!solver.using_active(expr.qualifier, section))
diags.add_diagnostic(diagnostic_op::error_ME005(*expr.qualifier, *section->name, expr.get_range()));
}
void using_label_checker::visit(const expressions::mach_expr_location_counter&) {}
void using_label_checker::visit(const expressions::mach_expr_default&) {}
void using_label_checker::visit(const expressions::mach_expr_literal& l) { l.get_data_definition().apply(*this); }

} // namespace hlasm_plugin::parser_library::checking
53 changes: 53 additions & 0 deletions parser_library/src/checking/using_label_checker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*/


#ifndef HLASMPLUGIN_PARSERLIBRARY_USING_LABEL_CHECKER_H
#define HLASMPLUGIN_PARSERLIBRARY_USING_LABEL_CHECKER_H

#include "diagnostic_consumer.h"
#include "expressions/mach_expr_visitor.h"

namespace hlasm_plugin::parser_library::context {
class dependency_solver;
} // namespace hlasm_plugin::parser_library::context

namespace hlasm_plugin::parser_library::checking {

class using_label_checker final : public expressions::mach_expr_visitor, diagnostic_consumer<diagnostic_op>
{
context::dependency_solver& solver;
diagnostic_consumer<diagnostic_op>& diags;

void add_diagnostic(diagnostic_op) const override;

public:
using_label_checker(context::dependency_solver& solver, diagnostic_consumer<diagnostic_op>& diags)
: solver(solver)
, diags(diags)
{}

// Inherited via mach_expr_visitor
void visit(const expressions::mach_expr_constant&) override;
void visit(const expressions::mach_expr_data_attr& attr) override;
void visit(const expressions::mach_expr_data_attr_literal& attr) override;
void visit(const expressions::mach_expr_symbol& expr) override;
void visit(const expressions::mach_expr_location_counter&) override;
void visit(const expressions::mach_expr_default&) override;
void visit(const expressions::mach_expr_literal& l) override;
};

} // namespace hlasm_plugin::parser_library::checking

#endif
4 changes: 2 additions & 2 deletions parser_library/src/context/hlasm_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ macro_def_ptr hlasm_context::add_macro(id_index name,
void hlasm_context::add_macro(macro_def_ptr macro)
{
const auto& m = macros_[macro->id] = std::move(macro);
// associate mnemonic if previously deleted by OPSYN
if (auto m_op = opcode_mnemo_.find(m->id); m_op != opcode_mnemo_.end() && !m_op->second)
// override associate mnemonic if exists
if (auto m_op = opcode_mnemo_.find(m->id); m_op != opcode_mnemo_.end())
m_op->second = opcode_t { m->id, m };
};

Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/context/hlasm_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ class hlasm_context
void using_resolve(diagnostic_s_consumer&);
index_t<using_collection> using_current() const;

const using_collection& usings() const { return *m_usings; }

using name_result = std::pair<bool, context::id_index>;
name_result try_get_symbol_name(const std::string& symbol);
};
Expand Down
7 changes: 3 additions & 4 deletions parser_library/src/context/instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ const ca_instruction& instruction::get_ca_instructions(std::string_view name)
std::span<const ca_instruction> instruction::all_ca_instructions() { return ca_instructions; }

constexpr assembler_instruction assembler_instructions[] = {
{ "*PROCESS", 1, -1, true, "" }, // TO DO
{ "*PROCESS", 1, -1, false, "" }, // TO DO
{ "ACONTROL", 1, -1, false, "<selection>+" },
{ "ADATA", 5, 5, false, "value1,value2,value3,value4,character_string" },
{ "AINSERT", 2, 2, false, "'record',BACK|FRONT" },
Expand Down Expand Up @@ -454,7 +454,6 @@ constexpr auto SI_2_s = instruction_format_definition_factory<mach_format::SI, d
constexpr auto SI_2_u = instruction_format_definition_factory<mach_format::SI, db_12_4_U, imm_8_U>::def();
constexpr auto SIL_2_s = instruction_format_definition_factory<mach_format::SIL, db_12_4_U, imm_16_S>::def();
constexpr auto SIL_2_u = instruction_format_definition_factory<mach_format::SIL, db_12_4_U, imm_16_U>::def();
constexpr auto SIY_2_uu = instruction_format_definition_factory<mach_format::SIY, db_12_4_U, imm_8_U>::def();
constexpr auto SIY_2_ss = instruction_format_definition_factory<mach_format::SIY, db_20_4_S, imm_8_S>::def();
constexpr auto SIY_2_su = instruction_format_definition_factory<mach_format::SIY, db_20_4_S, imm_8_U>::def();
constexpr auto SMI_3 = instruction_format_definition_factory<mach_format::SMI, mask_4_U, rel_addr_imm_16_S, db_12_4_U>::def();
Expand Down Expand Up @@ -754,7 +753,7 @@ constexpr machine_instruction machine_instructions[] = {
{ "CLIB", RIS_4, 638 },
{ "CLIH", RIL_a_2, 642 },
{ "CLIJ", RIE_c_4, 638 },
{ "CLIY", SIY_2_uu, 636 },
{ "CLIY", SIY_2_su, 636 },
{ "CLM", RS_b_3, 641 },
{ "CLMH", RSY_b_3_us, 641 },
{ "CLMY", RSY_b_3_us, 641 },
Expand Down Expand Up @@ -1226,7 +1225,7 @@ constexpr machine_instruction machine_instructions[] = {
{ "MVHHI", SIL_2_s, 773 },
{ "MVHI", SIL_2_s, 773 },
{ "MVI", SI_2_u, 773 },
{ "MVIY", SIY_2_uu, 773 },
{ "MVIY", SIY_2_su, 773 },
{ "MVN", SS_a_2_u, 785 },
{ "MVO", SS_b_2, 786 },
{ "MVPG", RRE_2, 1044 },
Expand Down
19 changes: 6 additions & 13 deletions parser_library/src/context/literal_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const semantics::instruction_si literal_pool::literal_postponed_statement::empty
const processing::processing_format literal_pool::literal_postponed_statement::dc_format(
processing::processing_kind::ORDINARY, processing::processing_form::ASM, processing::operand_occurence::PRESENT);

void literal_pool::generate_pool(diagnosable_ctx& diags)
void literal_pool::generate_pool(diagnosable_ctx& diags, index_t<using_collection> active_using)
{
ordinary_assembly_context& ord_ctx = hlasm_ctx.ord_ctx;

Expand All @@ -125,8 +125,9 @@ void literal_pool::generate_pool(diagnosable_ctx& diags)
it->second.loctr,
it->first.generation,
it->first.unique_id,
active_using,
});
auto bit_length = lit->evaluate_total_length(solver, diags);
auto bit_length = lit->evaluate_total_length(solver, checking::data_instr_type::DC, diags);
if (bit_length < 0)
continue;
size = (bit_length + 7) / 8;
Expand Down Expand Up @@ -155,6 +156,7 @@ void literal_pool::generate_pool(diagnosable_ctx& diags)
lit_val.loctr,
lit_key.generation,
lit_key.unique_id,
active_using,
});

if (!lit->access_data_def_type()) // unknown type
Expand All @@ -179,23 +181,14 @@ void literal_pool::generate_pool(diagnosable_ctx& diags)

if (!cycle_ok)
diags.add_diagnostic(diagnostic_op::error_E033(it->second.r));
else if (lit->get_dependencies(solver).contains_dependencies())
else
{
auto adder = ord_ctx.symbol_dependencies.add_dependencies(
std::make_unique<literal_postponed_statement>(lit, lit_val, hlasm_ctx.ids()),
{ lit_val.loctr, lit_key.generation, lit_key.unique_id });
{ lit_val.loctr, lit_key.generation, lit_key.unique_id, active_using });
adder.add_dependency();
adder.finish();
}
else
{
auto ddt = lit->access_data_def_type();
if (!ddt) // unknown type
continue;

auto ddo = semantics::data_def_operand::get_operand_value(*lit, solver, diags);
ddt->check_DC(ddo, diagnostic_collector(&diags, lit_val.stack));
}
}

m_pending_literals.clear();
Expand Down
4 changes: 3 additions & 1 deletion parser_library/src/context/literal_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
#include "id_storage.h"
#include "location.h"
#include "source_context.h"
#include "tagged_index.h"
#include "utils/similar.h"

namespace hlasm_plugin::parser_library::context {
class hlasm_context;
class using_collection;

class literal_pool
{
Expand Down Expand Up @@ -111,7 +113,7 @@ class literal_pool
id_index get_literal(
size_t generation, const std::shared_ptr<const expressions::data_definition>& dd, size_t unique_id) const;

void generate_pool(diagnosable_ctx& diags);
void generate_pool(diagnosable_ctx& diags, index_t<using_collection> active_using);
size_t current_generation() const { return m_current_literal_pool_generation; }

// testing
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/context/ordinary_assembly/address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ bool address::in_same_loctr(const address& addr) const

bool address::is_simple() const { return bases_.size() == 1 && bases_[0].second == 1; }

bool has_unresolved_spaces(const space_ptr sp)
bool has_unresolved_spaces(const space_ptr& sp)
{
if (!sp->resolved())
return true;
Expand Down
Loading