From e458b249671817f2cf9a89f9b8323105b5ee6391 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 7 Jan 2024 12:55:40 +0000 Subject: [PATCH] Parsing for anonymous types in interface declarations --- src/parse.c | 32 +++++++++++++++++++++++++++++--- test/parse/vhdl2019.vhd | 5 +++++ test/sem/lcs2016_16.vhd | 4 ++++ test/test_parse.c | 8 ++++++++ test/test_sem.c | 18 ++++++++++++++++++ 5 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 test/sem/lcs2016_16.vhd diff --git a/src/parse.c b/src/parse.c index 93836183..8c89f609 100644 --- a/src/parse.c +++ b/src/parse.c @@ -4554,6 +4554,32 @@ static tree_t p_expression(void) return expr; } +static type_t p_interface_type_indication(tree_t parent) +{ + // subtype_indication | anonymous_type_indication + + BEGIN("interface type indication"); + + if (peek() == tTYPE) { + require_std(STD_19, "anonymous type indication"); + + type_t type = p_anonymous_type_indication(); + + tree_t g = tree_new(T_GENERIC_DECL); + tree_set_loc(g, CURRENT_LOC); + tree_set_ident(g, ident_uniq("anonymous")); + tree_set_subkind(g, PORT_IN); + tree_set_class(g, C_TYPE); + tree_set_type(g, type); + + tree_add_generic(parent, g); + + return type; + } + else + return p_subtype_indication(); +} + static void p_interface_constant_declaration(tree_t parent, tree_kind_t kind, bool ordered) { @@ -4581,7 +4607,7 @@ static void p_interface_constant_declaration(tree_t parent, tree_kind_t kind, if ((mode == PORT_OUT || mode == PORT_INOUT) && !explicit_constant) class = C_VARIABLE; - type_t type = p_subtype_indication(); + type_t type = p_interface_type_indication(parent); tree_t init = NULL; if (optional(tASSIGN)) { @@ -4693,7 +4719,7 @@ static void p_interface_signal_declaration(tree_t parent, tree_kind_t kind, flags |= TREE_F_EXPLICIT_MODE; } - type = p_subtype_indication(); + type = p_interface_type_indication(parent); if (optional(tBUS)) flags |= TREE_F_BUS; @@ -4741,7 +4767,7 @@ static void p_interface_variable_declaration(tree_t parent, tree_kind_t kind) flags |= TREE_F_EXPLICIT_MODE; } - type_t type = p_subtype_indication(); + type_t type = p_interface_type_indication(parent); tree_t init = NULL; if (optional(tASSIGN)) { diff --git a/test/parse/vhdl2019.vhd b/test/parse/vhdl2019.vhd index cd6648cd..9acda991 100644 --- a/test/parse/vhdl2019.vhd +++ b/test/parse/vhdl2019.vhd @@ -91,3 +91,8 @@ entity E is type t9 is file of t1; ); end E; + +-- LCS-2015-016 +entity E is + port ( p : type is private ); +end entity; diff --git a/test/sem/lcs2016_16.vhd b/test/sem/lcs2016_16.vhd new file mode 100644 index 00000000..d4cd821c --- /dev/null +++ b/test/sem/lcs2016_16.vhd @@ -0,0 +1,4 @@ +entity ent1 is + generic ( g1 : type is private ); -- OK + port ( p1 : type is private ); -- OK +end entity; diff --git a/test/test_parse.c b/test/test_parse.c index 0764a2f1..16ba7f8b 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -3780,6 +3780,14 @@ START_TEST(test_vhdl2019) fail_unless(tree_class(e059g18) == C_TYPE); fail_unless(type_subkind(tree_type(e059g18)) == GTYPE_ARRAY); + tree_t e016 = parse(); + fail_if(e016 == NULL); + fail_unless(tree_kind(e016) == T_ENTITY); + fail_unless(tree_generics(e016) == 1); + + tree_t e016g0 = tree_generic(e016, 0); + fail_unless(tree_class(e016g0) == C_TYPE); + fail_unless(parse() == NULL); fail_if_errors(); diff --git a/test/test_sem.c b/test/test_sem.c index 9c364c4c..d2d1ba83 100644 --- a/test/test_sem.c +++ b/test/test_sem.c @@ -3458,6 +3458,23 @@ START_TEST(test_genpack4) } END_TEST +START_TEST(test_lcs2016_16) +{ + set_standard(STD_19); + + input_from_file(TESTDIR "/sem/lcs2016_16.vhd"); + + const error_t expect[] = { + { -1, NULL } + }; + expect_errors(expect); + + parse_and_check(T_ENTITY); + + check_expected_errors(); +} +END_TEST + Suite *get_sem_tests(void) { Suite *s = suite_create("sem"); @@ -3621,6 +3638,7 @@ Suite *get_sem_tests(void) tcase_add_test(tc_core, test_lcs2016_59); tcase_add_test(tc_core, test_issue770); tcase_add_test(tc_core, test_genpack4); + tcase_add_test(tc_core, test_lcs2016_16); suite_add_tcase(s, tc_core); return s; -- 2.39.2