diff --git a/src/names.c b/src/names.c index fe2efad24..4653177a8 100644 --- a/src/names.c +++ b/src/names.c @@ -553,13 +553,18 @@ static const symbol_t *symbol_for(scope_t *s, ident_t name) return NULL; } -static const decl_t *get_decl(const symbol_t *sym, unsigned nth) +static inline const decl_t *get_decl(const symbol_t *sym, unsigned nth) { assert(nth < sym->ndecls); - if (nth < INLINE_DECLS) - return &(sym->decls[nth]); - else - return &(sym->overflow[nth - INLINE_DECLS]); + return (nth < INLINE_DECLS) + ? &(sym->decls[nth]) : &(sym->overflow[nth - INLINE_DECLS]); +} + +static inline decl_t *get_decl_mutable(symbol_t *sym, unsigned nth) +{ + assert(nth < sym->ndecls); + return (nth < INLINE_DECLS) + ? &(sym->decls[nth]) : &(sym->overflow[nth - INLINE_DECLS]); } static decl_t *add_decl(symbol_t *sym) @@ -735,8 +740,7 @@ static symbol_t *make_visible(scope_t *s, ident_t name, tree_t decl, kind = ATTRIBUTE; for (int i = 0; i < sym->ndecls; i++) { - decl_t *dd = (i < INLINE_DECLS) - ? &(sym->decls[i]) : &(sym->overflow[i - INLINE_DECLS]); + decl_t *dd = get_decl_mutable(sym, i); if (dd->tree == decl) return sym; // Ignore duplicates @@ -1157,6 +1161,22 @@ void insert_name(nametab_t *tab, tree_t decl, ident_t alias) make_visible_slow(tab->top_scope, alias ?: tree_ident(decl), decl); } +void hide_name(nametab_t *tab, ident_t name) +{ + const symbol_t *exist = symbol_for(tab->top_scope, name); + if (exist == NULL || exist->owner == tab->top_scope) + return; + + symbol_t *sym = local_symbol_for(tab->top_scope, name); + + for (int i = 0; i < sym->ndecls; i++) { + decl_t *dd = get_decl_mutable(sym, i); + + if (dd->origin != tab->top_scope && dd->visibility == DIRECT) + dd->visibility = HIDDEN; + } +} + void insert_spec(nametab_t *tab, tree_t spec, spec_kind_t kind, ident_t ident, int depth) { @@ -1471,8 +1491,11 @@ tree_t resolve_name(nametab_t *tab, const loc_t *loc, ident_t name) return NULL; } - else if (sym->ndecls == 1) - return get_decl(sym, 0)->tree; + else if (sym->ndecls == 1) { + const decl_t *dd = get_decl(sym, 0); + if (dd->visibility != HIDDEN) + return dd->tree; + } // Check if all but one declartion is hidden int hidden = 0, overload = 0, subprograms = 0; @@ -1561,7 +1584,9 @@ tree_t resolve_name(nametab_t *tab, const loc_t *loc, ident_t name) return NULL; // Was an earlier error diag_t *d = diag_new(DIAG_ERROR, loc); - if (overload == 0) + if (hidden > 0 && hidden == sym->ndecls) + diag_printf(d, "declaration of %s is hidden", istr(name)); + else if (overload == 0) diag_printf(d, "multiple conflicting visible declarations of %s", istr(name)); else @@ -1584,7 +1609,7 @@ tree_t resolve_name(nametab_t *tab, const loc_t *loc, ident_t name) tb_printf(tb, " declaration of %s", istr(name)); type_t type = get_type_or_null(dd->tree); - if (type != NULL) + if (type != NULL && !is_type_decl(dd->tree)) tb_printf(tb, " as %s", type_pp(tree_type(dd->tree))); if (dd->origin->container != NULL) diff --git a/src/names.h b/src/names.h index ddeeddfe1..e0fd8e7f9 100644 --- a/src/names.h +++ b/src/names.h @@ -94,6 +94,8 @@ void insert_names_for_config(nametab_t *tab, tree_t unit); void insert_spec(nametab_t *tab, tree_t spec, spec_kind_t kind, ident_t ident, int depth); +void hide_name(nametab_t *tab, ident_t name); + ident_t get_implicit_label(tree_t t, nametab_t *tab); void continue_proc_labelling_from(tree_t t, nametab_t *tab); diff --git a/src/parse.c b/src/parse.c index cd93ae777..b5689fd8f 100644 --- a/src/parse.c +++ b/src/parse.c @@ -6225,6 +6225,7 @@ static void p_type_declaration(tree_t container) consume(tTYPE); ident_t id = p_identifier(); + hide_name(nametab, id); // Protected type bodies are broken out here to avoid having to // return a dummy type for them in p_full_type_declaration @@ -6297,9 +6298,14 @@ static tree_t p_subtype_declaration(void) BEGIN("subtype declaration"); consume(tSUBTYPE); + ident_t id = p_identifier(); + hide_name(nametab, id); + consume(tIS); + type_t sub = p_subtype_indication(); + consume(tSEMI); if (type_kind(sub) != T_SUBTYPE || type_has_ident(sub)) { @@ -6430,6 +6436,9 @@ static void p_constant_declaration(tree_t parent) LOCAL_IDENT_LIST ids = p_identifier_list(); + for (ident_list_t *it = ids; it != NULL; it = it->next) + hide_name(nametab, it->ident); + consume(tCOLON); type_t type = p_subtype_indication(); @@ -6799,6 +6808,9 @@ static void p_variable_declaration(tree_t parent) LOCAL_IDENT_LIST ids = p_identifier_list(); + for (ident_list_t *it = ids; it != NULL; it = it->next) + hide_name(nametab, it->ident); + consume(tCOLON); type_t type = p_subtype_indication(); @@ -6856,6 +6868,9 @@ static void p_signal_declaration(tree_t parent) LOCAL_IDENT_LIST ids = p_identifier_list(); + for (ident_list_t *it = ids; it != NULL; it = it->next) + hide_name(nametab, it->ident); + consume(tCOLON); type_t type = p_subtype_indication(); diff --git a/test/parse/visibility8.vhd b/test/parse/visibility8.vhd new file mode 100644 index 000000000..16270f6d7 --- /dev/null +++ b/test/parse/visibility8.vhd @@ -0,0 +1,26 @@ +entity visibility8 is +end entity; + +architecture test of visibility8 is + constant c1 : integer := 1; + subtype t1 is integer; + type t2 is range 1 to 3; + signal s1 : bit_vector(1 to 6); + shared variable v1 : integer; +begin + + b1: block is + signal s1 : bit_vector(1 to s1'length); -- Error + begin + end block; + + p1: process is + constant c1 : integer := c1; -- Error + subtype t1 is t1; -- Error + type t2 is range t2'left to 5; -- Error + variable v1 : integer := v1; -- Error + begin + wait; + end process; + +end architecture;