More robust handling of identifiers out of scope.

Handle the (otherwise and error) case of an identifier
used or accessed outside any scope.
This commit is contained in:
Stephen Williams 2019-09-30 18:46:26 -07:00
parent ab0c4bb8c7
commit c02f22732d
3 changed files with 20 additions and 6 deletions

14
parse.y
View File

@ -2358,9 +2358,13 @@ variable_lifetime
{ if (!gn_system_verilog()) {
yyerror(@1, "error: overriding the default variable lifetime "
"requires SystemVerilog.");
} else if ($1 != pform_peek_scope()->default_lifetime) {
yyerror(@1, "sorry: overriding the default variable lifetime "
"is not yet supported.");
} else {
LexicalScope*lex_scope = pform_peek_scope();
assert(lex_scope);
if ($1 != lex_scope->default_lifetime) {
yyerror(@1, "sorry: overriding the default variable lifetime "
"is not yet supported.");
}
}
var_lifetime = $1;
}
@ -5690,7 +5694,9 @@ register_variable
$$ = $1;
}
| IDENTIFIER dimensions_opt '=' expression
{ if (pform_peek_scope()->var_init_needs_explicit_lifetime()
{ LexicalScope*lex_scope = pform_peek_scope();
assert(lex_scope);
if (lex_scope->var_init_needs_explicit_lifetime()
&& (var_lifetime == LexicalScope::INHERITED)) {
cerr << @3 << ": warning: Static variable initialization requires "
"explicit lifetime in this context." << endl;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2017,2019 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -398,7 +398,6 @@ static LexicalScope* lexical_scope = 0;
LexicalScope* pform_peek_scope(void)
{
assert(lexical_scope);
return lexical_scope;
}
@ -639,6 +638,14 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
PEIdent* pform_new_ident(const pform_name_t&name)
{
LexicalScope*scope = pform_peek_scope();
// If there is no scope (should not be possible) then it is
// certainly not imported from a package. This case should
// only be triggered in otherwise incorrect syntax.
if (scope == 0) {
return new PEIdent(name);
}
assert(scope);
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.front().name);
if (pkg == scope->imports.end())
return new PEIdent(name);

View File

@ -75,6 +75,7 @@ void pform_end_package_declaration(const struct vlltype&loc)
void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
{
LexicalScope*scope = pform_peek_scope();
assert(scope);
if (ident) {
perm_string use_ident = lex_strings.make(ident);