Skip to content

Commit

Permalink
Allow 'INSTANCE_NAME for processes and blocks. Issue #45
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Mar 2, 2014
1 parent 214d241 commit 86d8e6d
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 70 deletions.
24 changes: 5 additions & 19 deletions src/cgen.c
Expand Up @@ -477,20 +477,6 @@ static bool cgen_const_bounds(type_t type)
}
}

static class_t cgen_get_class(tree_t decl)
{
switch (tree_kind(decl)) {
case T_VAR_DECL:
return C_VARIABLE;
case T_SIGNAL_DECL:
return C_SIGNAL;
case T_CONST_DECL:
return C_CONSTANT;
default:
return tree_class(decl);
}
}

static int cgen_array_dims(type_t type)
{
assert(type_is_array(type));
Expand Down Expand Up @@ -580,7 +566,7 @@ static LLVMValueRef cgen_array_dir(type_t type, int dim, LLVMValueRef var)

LLVMValueRef uarray;
tree_t decl = tree_ref(value);
if (cgen_get_class(decl) == C_SIGNAL)
if (class_of(decl) == C_SIGNAL)
uarray = cgen_signal_nets(decl);
else
uarray = cgen_get_var(decl, NULL);
Expand Down Expand Up @@ -1668,7 +1654,7 @@ static LLVMValueRef cgen_uarray_field(tree_t expr, int field, cgen_ctx_t *ctx)
if (tree_kind(expr) == T_REF) {
// Avoid loading all the array data if possible
tree_t decl = tree_ref(expr);
if (cgen_get_class(decl) == C_SIGNAL) {
if (class_of(decl) == C_SIGNAL) {
meta = cgen_signal_nets(decl);
assert(meta != NULL);
}
Expand Down Expand Up @@ -2793,7 +2779,7 @@ static LLVMValueRef cgen_ref(tree_t t, cgen_ctx_t *ctx)
// Fall-through

case T_SIGNAL_DECL:
if (cgen_get_class(decl) == C_SIGNAL) {
if (class_of(decl) == C_SIGNAL) {
LLVMValueRef nets = cgen_signal_nets(decl);
if (type_is_array(type))
return cgen_vec_load(nets, type, type, false, ctx);
Expand Down Expand Up @@ -2893,7 +2879,7 @@ static LLVMValueRef cgen_array_ref(tree_t t, cgen_ctx_t *ctx)
array = cgen_expr(tree_value(decl), ctx);
}
else {
class = cgen_get_class(decl);
class = class_of(decl);

switch (class) {
case C_VARIABLE:
Expand Down Expand Up @@ -2980,7 +2966,7 @@ static LLVMValueRef cgen_array_slice(tree_t t, cgen_ctx_t *ctx)

}
else {
switch (cgen_get_class(decl)) {
switch (class_of(decl)) {
case C_VARIABLE:
case C_DEFAULT:
case C_CONSTANT:
Expand Down
57 changes: 57 additions & 0 deletions src/common.c
Expand Up @@ -367,3 +367,60 @@ int record_field_to_net(type_t type, ident_t name)

assert(false);
}

class_t class_of(tree_t t)
{
switch (tree_kind(t)) {
case T_VAR_DECL:
return C_VARIABLE;
case T_SIGNAL_DECL:
return C_SIGNAL;
case T_CONST_DECL:
return C_CONSTANT;
case T_PORT_DECL:
return tree_class(t);
case T_ENUM_LIT:
case T_GENVAR:
case T_ALIAS:
case T_FIELD_DECL:
return C_DEFAULT;
case T_UNIT_DECL:
return C_UNITS;
case T_ARCH:
return C_ARCHITECTURE;
case T_FUNC_DECL:
case T_FUNC_BODY:
return C_FUNCTION;
case T_PROC_DECL:
case T_PROC_BODY:
return C_PROCEDURE;
case T_ENTITY:
return C_ENTITY;
case T_TYPE_DECL:
return C_TYPE;
case T_FILE_DECL:
return C_FILE;
case T_PROCESS:
case T_BLOCK:
return C_LABEL;
case T_COMPONENT:
return C_COMPONENT;
default:
fatal("missing class_of for %s", tree_kind_str(tree_kind(t)));
}
}

bool class_has_type(class_t c)
{
switch (c) {
case C_LABEL:
case C_ENTITY:
case C_ARCHITECTURE:
case C_COMPONENT:
case C_CONFIGURATION:
case C_PACKAGE:
return false;
default:
return true;
}
}
2 changes: 2 additions & 0 deletions src/common.h
Expand Up @@ -39,6 +39,8 @@ const char *package_signal_path_name(ident_t i);
bool parse_value(type_t type, const char *str, int64_t *value);
tree_t make_ref(tree_t to);
int record_field_to_net(type_t type, ident_t name);
class_t class_of(tree_t t);
bool class_has_type(class_t c);

//
// Utility typedefs
Expand Down
3 changes: 3 additions & 0 deletions src/elab.c
Expand Up @@ -998,6 +998,9 @@ static void elab_process(tree_t t, const elab_ctx_t *ctx)
break;
}
}

tree_add_attr_str(t, inst_name_i,
ident_prefix(ctx->inst, ident_new(":"), '\0'));
}

static void elab_stmts(tree_t t, const elab_ctx_t *ctx)
Expand Down
67 changes: 21 additions & 46 deletions src/sem.c
Expand Up @@ -1603,8 +1603,8 @@ static void sem_add_attributes(tree_t decl)
type_t std_bool = sem_std_type("BOOLEAN");

type_t type;
tree_kind_t kind = tree_kind(decl);
if ((kind != T_ARCH) && (kind != T_ENTITY) && (kind != T_COMPONENT))
class_t class = class_of(decl);
if (class_has_type(class))
type = tree_type(decl);
else
type = type_new(T_NONE);
Expand Down Expand Up @@ -1670,10 +1670,9 @@ static void sem_add_attributes(tree_t decl)
"last_event", type, NULL));
}

if (is_signal || (decl_kind == T_ARCH) || (decl_kind == T_ENTITY)
|| (decl_kind == T_COMPONENT) || (decl_kind == T_FUNC_DECL)
|| (decl_kind == T_FUNC_BODY) || (decl_kind == T_PROC_DECL)
|| (decl_kind == T_PROC_BODY)) {
if (is_signal || (class == C_ARCHITECTURE) || (class == C_ENTITY)
|| (class == C_FUNCTION) || (class == C_PROCEDURE)
|| (class == C_LABEL)) {
type_t std_string = sem_std_type("STRING");

ident_t path_name_i = ident_new("PATH_NAME");
Expand Down Expand Up @@ -2021,39 +2020,9 @@ static bool sem_check_stmts(tree_t t, tree_t (*get_stmt)(tree_t, unsigned),
bool ok = true;
for (int i = 0; i < nstmts; i++) {
tree_t s = get_stmt(t, i);
ok = sem_check(s) && ok;
ok = scope_insert(s) && sem_check(s) && ok;
}

// Check for duplicate statements: if the number of statements is small
// then it is simpler to do this with the naive O(n^2) algorithm but when
// the number is large it is more efficient to use a hash table

const bool use_hash = (nstmts >= 128);
hash_t *hash = NULL;
if (use_hash)
hash = hash_new(nstmts * 2, true);

for (int i = 0; i < nstmts; i++) {
tree_t s = get_stmt(t, i);
ident_t label = tree_ident(s);

bool duplicate = false;
if (use_hash)
duplicate = hash_put(hash, label, NULL);
else {
for (int j = 0; (j < i) && !duplicate; j++) {
if (tree_ident(get_stmt(t, j)) == label)
duplicate = true;
}
}

if (duplicate)
sem_error(s, "duplicate statement label %s", istr(label));
}

if (use_hash)
hash_free(hash);

return ok;
}

Expand Down Expand Up @@ -2251,6 +2220,8 @@ static bool sem_check_sensitivity(tree_t t)

static bool sem_check_process(tree_t t)
{
sem_add_attributes(t);

scope_push(NULL);

bool ok = sem_check_sensitivity(t);
Expand Down Expand Up @@ -4174,8 +4145,9 @@ static bool sem_check_ref(tree_t t)
int n = 0;
do {
if ((next = scope_find_nth(name, n))) {
tree_kind_t kind = tree_kind(next);
if ((kind == T_ENTITY) || (kind == T_ARCH) || (kind == T_COMPONENT))
class_t class = class_of(next);
if ((class == C_ENTITY) || (class == C_ARCHITECTURE)
|| (class == C_COMPONENT) || (class == C_LABEL))
continue;

type_t type = tree_type(next);
Expand Down Expand Up @@ -4406,14 +4378,15 @@ static bool sem_check_attr_ref(tree_t t)

special = true;
}
else if ((kind == T_ARCH) || (kind == T_ENTITY)
|| (kind == T_COMPONENT) || (kind == T_FUNC_DECL)
|| (kind == T_FUNC_BODY) || (kind == T_PROC_DECL)
|| (kind == T_PROC_BODY)) {
// Special case for attributes of entities and architectures
tree_set_ref(name, decl);
else {
class_t class = class_of(decl);
if (!class_has_type(class) || (class == C_PROCEDURE)
|| (class == C_FUNCTION)) {
// Special case for attributes of entities, architectures, etc.
tree_set_ref(name, decl);

special = true;
special = true;
}
}
}

Expand Down Expand Up @@ -5318,6 +5291,8 @@ static bool sem_check_block(tree_t t)
{
scope_push(NULL);

sem_add_attributes(t);

bool ok = true;

const int ndecls = tree_decls(t);
Expand Down
3 changes: 0 additions & 3 deletions src/tree.c
Expand Up @@ -1014,9 +1014,6 @@ tree_t tree_ref(tree_t t)

void tree_set_ref(tree_t t, tree_t decl)
{
assert(tree_kind_in(decl, decl_kinds, ARRAY_LEN(decl_kinds))
|| (decl->kind == T_ENUM_LIT)
|| tree_kind_in(decl, top_level_kinds, ARRAY_LEN(top_level_kinds)));
lookup_item(t, I_REF)->tree = decl;
}

Expand Down
4 changes: 3 additions & 1 deletion src/tree.h
Expand Up @@ -48,7 +48,9 @@ typedef enum class {
C_TYPE,
C_SUBTYPE,
C_LABEL,
C_PROCEDURE
C_PROCEDURE,
C_LITERAL,
C_UNITS
} class_t;

typedef enum param_kind {
Expand Down
2 changes: 2 additions & 0 deletions test/regress/gold/issue45.txt
@@ -0,0 +1,2 @@
0ms+0: Report Note: :issue45(a):b:p:
0ms+0: Report Note: :issue45(a):b:
19 changes: 19 additions & 0 deletions test/regress/issue45.vhd
@@ -0,0 +1,19 @@
entity issue45 is
begin
end entity issue45;

architecture a of issue45 is

begin

b: block is
begin
p : process
begin
report p'instance_name;
report b'instance_name;
wait;
end process p;
end block;

end architecture a;
1 change: 1 addition & 0 deletions test/regress/testlist.txt
Expand Up @@ -211,3 +211,4 @@ elab21 normal
record9 normal
record10 normal
real2 normal
issue45 normal,gold
2 changes: 1 addition & 1 deletion test/test_sem.c
Expand Up @@ -801,7 +801,7 @@ START_TEST(test_seq)
{ 187, "type of next condition must be BOOLEAN" },
{ 190, "cannot use next outside loop" },
{ 192, "no nested loop with label FOO" },
{ 205, "duplicate statement label DUP" },
{ 205, "DUP already declared in this region" },
{ -1, NULL }
};
expect_errors(expect);
Expand Down

0 comments on commit 86d8e6d

Please sign in to comment.